c#与UserControls的跨线程错误

时间:2021-06-09 10:58:53

Here is my situation:

这是我的情况:

I instantiated a c# usercontrol on a main thread, but it is not added to the form.

我在主线程上实例化了一个c#usercontrol,但它没有添加到表单中。

//global declaration
usercontrol1 datacontrol;

 constructor()
{
.......
     datacontrol = new usercontrol1();
........
}

I then have an asyhcnronous background thread that fires an event that is handled by the instantiated datacontrol. The event handler has a:

然后我有一个asyhcnnronous后台线程,它触发由实例化的datacontrol处理的事件。事件处理程序有一个:

if(InvokeRequired){BeginInvoke(..);}

This should prevent any cross-threaded calls from being made. However when this gets called InvokeRequired is false so the handler is not invoked on the correct thread. So in the handler when I attemped a this.labelname.text ="blah" a cross-thread exception is thrown.

这应该可以防止进行任何跨线程调用。但是当调用它时,InvokeRequired为false,因此不会在正确的线程上调用处理程序。所以在我尝试使用this.labelname.text =“blah”的处理程序中,抛出了一个跨线程异常。

However if I add the control to a panel on the mainform, and remove it, then allow the background thread to fire the event. The handler enters but this time 'InvokeRequired' is set to true so it properly invokes itself in the mainthreads context avoiding the exception.

但是,如果我将控件添加到主窗体上的面板,并将其删除,则允许后台线程触发该事件。处理程序进入但此时'InvokeRequired'设置为true,因此它在mainthreads上下文中正确调用自身以避免异常。

Can someone explain to me why the act of adding it to a panel then removing it fixes the error?

有人可以向我解释为什么将它添加到面板然后删除它的行为修复了错误?

There is no onLoad events for the form so everything should be properly instantiated without it being drawn.

表单上没有onLoad事件,因此所有内容都应该在没有绘制的情况下正确实例化。

thanks! stephanie

谢谢!斯蒂芬妮

2 个解决方案

#1


4  

This is probably because the handle for the control has not yet been created. If you reference dataform.Handle in your constructor, it should create the handle and set the thread ID appropriately, so InvokeRequired will return true later.

这可能是因为尚未创建控件的句柄。如果在构造函数中引用dataform.Handle,它应该创建句柄并适当地设置线程ID,因此InvokeRequired稍后将返回true。

You can also force the creation of a handle with CreateControl, but only if the control is visible.

您也可以使用CreateControl强制创建句柄,但前提是控件是可见的。

#2


1  

When you add a Control (or Form) to a parent, it sets of the Creating of WindowHandles. Apparently it is also needed to initialize the Execution context for the InvokeRequired logic.

将控件(或表单)添加到父级时,它会创建WindowHandles。显然,还需要初始化InvokeRequired逻辑的Execution上下文。

So, don't assume that a created but never-shown Control or Form behaves 'normally'.

因此,不要假设已创建但从未显示的控件或表单“正常”运行。

#1


4  

This is probably because the handle for the control has not yet been created. If you reference dataform.Handle in your constructor, it should create the handle and set the thread ID appropriately, so InvokeRequired will return true later.

这可能是因为尚未创建控件的句柄。如果在构造函数中引用dataform.Handle,它应该创建句柄并适当地设置线程ID,因此InvokeRequired稍后将返回true。

You can also force the creation of a handle with CreateControl, but only if the control is visible.

您也可以使用CreateControl强制创建句柄,但前提是控件是可见的。

#2


1  

When you add a Control (or Form) to a parent, it sets of the Creating of WindowHandles. Apparently it is also needed to initialize the Execution context for the InvokeRequired logic.

将控件(或表单)添加到父级时,它会创建WindowHandles。显然,还需要初始化InvokeRequired逻辑的Execution上下文。

So, don't assume that a created but never-shown Control or Form behaves 'normally'.

因此,不要假设已创建但从未显示的控件或表单“正常”运行。

相关文章