C# DLL会导致Winforms UI在某些情况下运行缓慢 我有一个 VooObjs类,它利用C++ DLL从摄像头捕获图像和视频。我被告知DLL使用DirectShow来实现这一点。它似乎也启动了一些我无法控制的线程
C# DLL会导致Winforms UI在某些情况下运行缓慢 我有一个 VooObjs类,它利用C++ DLL从摄像头捕获图像和视频。我被告知DLL使用DirectShow来实现这一点。它似乎也启动了一些我无法控制的线程,c#,dll,user-interface,C#,Dll,User Interface,VideoObject类本身似乎运行良好;我可以拍摄图像和视频。但是,它的使用会对主UI的性能产生负面影响:它变得非常滞后 如果我像这样实例化我的VideoObject public partial class ParentForm : Form private VideoObject videoObject; public ParentForm() { videoObject = new VideoObject(); } } 然后UI变得非
VideoObject
类本身似乎运行良好;我可以拍摄图像和视频。但是,它的使用会对主UI的性能产生负面影响:它变得非常滞后
如果我像这样实例化我的VideoObject
public partial class ParentForm : Form
private VideoObject videoObject;
public ParentForm()
{
videoObject = new VideoObject();
}
}
然后UI变得非常滞后。我的猜测是,无论VideoObject
的底层DLL在做什么,它都会影响我的应用程序的UI线程
现在,我可以通过在MTA线程中启动VideoObject
实例来缓解这种滞后。(我对C#完全陌生,所以我猜下面的内容可能不是很聪明。)
现在,我可以与videoObject
实例交互,UI不会延迟,但前提是我不在表单的构造函数中进一步引用该实例
如果我在表单的构造函数中以任何方式与这个线程实例交互,UI将再次变得滞后。就好像在我表单的构造函数中,与VideoObject
实例的任何直接交互都会导致UI的滞后行为
有人对我看到的行为有什么见解吗
编辑:我可能应该澄清我所说的“laggy”是什么意思。我的意思是,主面板的UI会变得永远滞后和缓慢。没有其他任何东西受到影响;VideoObject上的所有操作都按预期工作,不会以任何方式运行得较慢或延迟
如果我不“触摸”窗体构造函数中的VideoObject,UI就可以完美地工作。随后调用VideoObject的方法也不会导致UI运行缓慢
这一切似乎都取决于我是否在主窗体的构造函数中访问VideoObject。每次调用Video对象上的方法时,它一定会有一些开销,暂时阻止用于与Video对象交互的线程。当调用方法或实例化对象时,视频组件可能必须将大型对象加载到内存中 您是否尝试过对视频对象上的方法进行异步调用?在等待视频对象从其正在执行的操作返回时,有效地避免了阻塞 如果不知道视频组件的细节,很难做出猜测 您可以考虑的一件事是,将视频对象包装在WCF服务中,并将其托管在自己的进程中,然后使用NetTcpBinding与组件交互
每次调用视频对象上的方法时,它必须有一些开销,暂时阻止用于与视频对象交互的线程。当调用方法或实例化对象时,视频组件可能必须将大型对象加载到内存中 您是否尝试过对视频对象上的方法进行异步调用?在等待视频对象从其正在执行的操作返回时,有效地避免了阻塞 如果不知道视频组件的细节,很难做出猜测 您可以考虑的一件事是,将视频对象包装在WCF服务中,并将其托管在自己的进程中,然后使用NetTcpBinding与组件交互
谢谢您的回复。对象初始化时会有一些初始开销,但除此之外几乎没有。即使我没有与实例交互,UI仍然非常滞后。我认为DLL中的某些“隐藏”导致了这个问题。我做了一个编辑,试图更好地解释这些症状。再次干杯。是的,视频组件本质上公开了DLL的功能。但是我没有DLL的代码;我只听说它使用DirectShow!谢谢你的回复。对象初始化时会有一些初始开销,但除此之外几乎没有。即使我没有与实例交互,UI仍然非常滞后。我认为DLL中的某些“隐藏”导致了这个问题。我做了一个编辑,试图更好地解释这些症状。再次干杯。是的,视频组件本质上公开了DLL的功能。但是我没有DLL的代码;我只听说它使用DirectShow!
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();
}
}