我有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行。
如果你已经走了这么远,那就太好了。然而,不幸的是,你还没有完成。当您现在处理多个线程时,必须确保以线程安全的方式访问对象。长话短说,看看这个答案。
编辑:一些修正