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

时间:2015-02-23 12:26:43

标签: c# multithreading events main

我有MainForm课程和一些Engine课程用于相机控制。在Engine类中,我有一些Camera对象,它是来自相机制作人的SDK的一部分。 此CameraOnNewFrame个可用事件,因此我将初始化:

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 fps),因为主线程延迟也会延迟。

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

1 个答案:

答案 0 :(得分:1)

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

我相信您已在MainForm中初始化了Engine类。如果你想从另一个线程引发事件,那么这个对象必须在另一个线程中初始化。

我相信您应该尝试在MainForm构造函数中创建一个新的Thread

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保留一个字段。但是,您需要为要运行的新线程编写一个函数。我们知道它会初始化您的Engine类,但并非全部。只是为了确保线程没有完成你运行它的功能,在线程函数的底部添加一些检查,如下所示:

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();
}

如果您愿意,可以将this.isShown = false行放入OnFormClosed()事件中。

如果你走得这么远,那很好。不幸的是,你还没有完成。由于您现在正在处理多个线程,因此必须确保以线程安全的方式访问对象。长话短说,请查看answer

编辑:一些更正