我有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 fps),因为主线程延迟也会延迟。
是否有可能确保某种方式,Engine
对象(或Camera
中的Engine
对象)将从其自己的线程而不是主线程中引发事件?换句话说,确保此事件以SDK生产者设置的速率提高,而不是依赖于我的主线程。
答案 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。
编辑:一些更正