Gra*_*ant 9 c# multithreading winforms
我正在使用一个winforms控件,它既是一个GUI元素,也是一些尚未向开发人员公开的内部处理.当这个组件被实例化时,它可能需要5到15秒才能准备就绪,所以我想做的就是将它放在另一个线程上,当它完成时将它带回gui线程并将其放在我的表单上.问题是这会(并且有)导致跨线程异常.
通常,当我使用工作线程时,它只使用简单的数据对象,我可以在处理完成后推回,然后使用已经在主线程上的控件,但我从来不需要以这种方式移动整个控件.
有谁知道这是否可能,如果可能,如何?如果不是如何处理这样的问题,哪里有可能锁定主gui?
你不需要锁定GUI,你只需要调用invoke:
Windows 窗体中的控件绑定到特定线程,并且不是线程安全的。因此,如果您从不同的线程调用控件的方法,则必须使用控件的调用方法之一将调用封送到正确的线程。此属性可用于确定是否必须调用调用方法,如果您不知道哪个线程拥有控件,这会很有用。参考
代码如下:
public delegate void ComponentReadyDelegate(YourComponent component);
public void LoadComponent(YourComponent component)
{
if (this.InvokeRequired)
{
ComponentReadyDelegate e = new ComponentReadyDelegate(LoadComponent);
this.BeginInvoke(e, new object[]{component});
}
else
{
// The component is used by a UI control
component.DoSomething();
component.GetSomething();
}
}
// From the other thread just initialize the component
// and call the LoadComponent method on the GUI.
component.Initialize(); // 5-15 seconds
yourForm.LoadComponent(component);
Run Code Online (Sandbox Code Playgroud)
通常从另一个线程调用LoadComponent
会导致跨线程异常,但通过上述实现,该方法将在 GUI 线程上调用。
InvokeRequired
告诉你如果:
调用者在对控件进行方法调用时必须调用调用方法,因为调用者与创建控件的线程位于不同的线程上。 参考
更新:
所以,如果我理解正确的话,控制对象是在 GUI 线程以外的线程上创建的,因此,即使您能够将它传递给 GUI 线程,您仍然无法在不导致交叉的情况下使用它。线程异常。解决方案是在 GUI 线程上创建对象,但在单独的线程上初始化它:
public partial class MyForm : Form
{
public delegate void ComponentReadyDelegate(YourComponent component);
private YourComponent _component;
public MyForm()
{
InitializeComponent();
// The componet is created on the same thread as the GUI
_component = new YourComponent();
ThreadPool.QueueUserWorkItem(o =>
{
// The initialization takes 5-10 seconds
// so just initialize the component in separate thread
_component.Initialize();
LoadComponent(_component);
});
}
public void LoadComponent(YourComponent component)
{
if (this.InvokeRequired)
{
ComponentReadyDelegate e = new ComponentReadyDelegate(LoadComponent);
this.BeginInvoke(e, new object[]{component});
}
else
{
// The component is used by a UI control
component.DoSomething();
component.GetSomething();
}
}
}
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
4277 次 |
最近记录: |