我有一个VideoObject
类,它使用c++ DLL从网络摄像头捕获图像和视频。我被告知DLL使用DirectShow来做到这一点。它似乎还启动了几个我无法控制的线程。
VideoObject
类本身似乎工作得很好;我可以捕捉图像和视频。然而,它的使用会对主UI的性能产生负面影响:它会变得非常滞后。
如果我像这样实例化VideoObject
public partial class ParentForm : Form
private VideoObject videoObject;
public ParentForm()
{
videoObject = new VideoObject();
}
}
则UI变得非常滞后。我的猜测是,无论VideoObject
的底层DLL正在做什么,它都会影响我的应用程序的UI线程。
现在,我可以通过在自己的MTA线程中启动VideoObject
实例来减轻这种延迟。(我对c#完全陌生,所以我猜下面的代码可能不是很聪明。)
public partial class ParentForm : Form
private VideoObject videoObject;
private Thread videoObjectThread;
public ParentForm()
{
videoObjectThread = new Thread(new ThreadStart(() => videoObject = new VideoObject()));
videoObjectThread.SetApartmentState(ApartmentState.MTA);
videoObjectThread.Start();
}
}
我现在可以与videoObject
实例交互,UI不会滞后,但前提是我不再在Form的构造函数中引用该实例。
如果我以任何方式在Form的构造函数中与这个线程实例交互,UI将再次变得滞后。这就好像任何直接的交互与VideoObject
的实例在我的表单的构造函数会导致UI的滞后行为。
有人对我所看到的行为有什么见解吗?
编辑:我可能应该澄清我所说的'laggy'是什么意思。我的意思是,主面板的UI变得永远滞后和缓慢。没有其他东西受到影响;VideoObject上的所有操作都按预期工作,不会以任何方式运行较慢或延迟。
如果我不"触摸"窗体的构造函数中的VideoObject, UI工作完美。随后调用VideoObject的方法也不会导致UI运行缓慢。
这一切似乎取决于我是否访问主表单的构造函数中的VideoObject
每次调用Video对象上的方法时,它必须有一些开销,临时阻塞用于与视频对象交互的线程。当方法被调用或对象被实例化时,Video组件可能需要将大的对象加载到内存中。
你试过异步调用视频对象上的方法吗?在等待视频对象从它正在做的任何事情返回时,有效地不阻塞。
如果不知道视频组件的细节,就很难猜测。
你可以考虑的一件事是也许将视频对象包装在WCF服务中,并将其托管在自己的进程中,然后使用netttcpbinding与组件交互。
http://msdn.microsoft.com/en-us/library/bb332338.aspx http://msdn.microsoft.com/en-us/library/system.servicemodel.nettcpbinding.aspx