我的InvokeRequied#2出了什么问题?

时间:2012-01-20 19:09:28

标签: c# .net multithreading invokerequired

第一个主题是What wrong with my InvokeRequied

我按照他向我推荐的答案,但我发现了一个新问题。

下图的结果是跨线程异常。

我的代码出了什么问题?

如何解决这个问题?

enter image description here

1 个答案:

答案 0 :(得分:9)

根据MSDN InvokeRequired即使在false应为InvokeRequired的情况下也可以返回true - 即在您访问InvokeRequired的情况下在创建该控件/表单(或其父项)的Handle之前。

基本上,您的支票不完整会导致您看到的结果。

您需要检查IsHandleCreated - 如果是false,那么无论Invoke返回什么,您都需要使用BeginInvoke / InvokeRequired

[UPDATE] 的 BUT : 由于Invoke / BeginInvoke检查哪个线程创建了Handle来实现他们的魔法,因此这通常无法有效运行... [/ UPDATE]

只有当IsHandleCreatedtrue时,您才会根据InvokeRequired返回的内容采取行动 - 以下内容:

if (control.IsHandleCreated)
{
    if (control.InvokeRequired)
    {
        control.BeginInvoke(action);
    }
    else
    {
        action.Invoke();
    }
}
else 
{ 
    // in this case InvokeRequired might lie - you need to make sure that this never happens! 
    throw new Exception ( "Somehow Handle has not yet been created on the UI thread!" );
}

[UPDATE]

因此,以下内容对于避免此问题很重要

始终确保在第一次访问UI线程以外的线程之前已创建Handle

根据MSDN,您只需要在UI线程中引用control.Handle以强制创建它 - 在您的代码中,这必须在您第一次从任何线程访问该控件/表单之前发生那不是UI线程。

[/ UPDATE]