C#在另一个线程上引发事件



我有MainForm类和一些用于相机控制的Engine类。在Engine类中,我有一些Camera对象,它是相机制造商SDK的一部分。这个Camera有可用的OnNewFrame事件,所以我将初始化:

camera.OnNewFrame += frameAcquired;

frameAcquired也是Engine类的成员。

 private void frameAcquired(object sender, EventArgs e)
 {
    /* this event should periodically raise after ~17ms,
       but sometimes it hangs for a short time 
       (when I overloads main thread) */
 }

Engine对象是MainForm类的成员。在这里,我正在显示来自相机的图像,并做一些其他的图形工作。问题是MainForm线程有时会挂起很短的时间。这对于显示来说并不重要,但对于camera.OnNewFrame事件(我使用的是60帧/秒)来说很重要,因为这也是由于主线程延迟而延迟的。

是否可以通过某种方式确保Engine对象(或Engine中的Camera对象)将从它自己的线程而不是从主线程引发事件?换句话说,请确保此事件提高SDK生产者设置的速率,而不是依赖于我的主线程。

不久前我也遇到过类似的问题。我已经在C++/CLI中处理过它,所以同样的方法也应该在C#中使用。

我相信您已经在MainForm中初始化了Engine类。如果要从另一个线程引发事件,则必须在另一个螺纹中初始化此对象。

我认为您应该尝试在MainForm构造函数中创建一个新线程:

MyForm()
{
    //rest of your constructor
    cameraThread = new Thread(new ParameterizedThreadStart(CameraRun));
    cameraThread.Name = "Camera Thread";
    cameraThread.Start(this);
    while (!cameraThread.IsAlive)
        Thread::Sleep(1);
}

通过这种方式,您可以在MyForm类中为cameraThread保留一个字段。尽管如此,您还是需要为新线程编写一个函数来运行。我们知道它会初始化你的引擎类,但这还不是全部。为了确保线程没有完成你给它运行的函数,在线程函数的底部添加一些检查,如下所示:

void CameraRun(Object myForm)
{
    //you can use (myForm as MyForm)
    //and make calls from here
    /*
    Engine initialization etc
    */
    while((myForm as MyForm).isShown)
        Sleep(100);
}

cameraThread应该连接回MainForm析构函数中的主代码。

~MyForm()
{
    //rest of your destructor
    this.isShown=false;
    cameraThread.Join();
}

如果您愿意,可以在OnFormClosed()事件中添加this.isShown=false行。

如果你已经走了这么远,那就太好了。然而,不幸的是,你还没有完成。当您现在处理多个线程时,必须确保以线程安全的方式访问对象。长话短说,看看这个答案。

编辑:一些修正

相关内容

  • 没有找到相关文章

最新更新