我的InvokeRequired有什么问题 #2?

3
第一个话题是关于我的InvokeRequired出了什么问题
我按照他建议的方法去做,但发现了一个新问题。
下面图片的结果是跨线程异常。
我的代码有什么问题?
如何解决这个问题? enter image description here
1个回答

11
根据MSDN的说明,即使在应该返回true的情况下,InvokeRequired也可能返回false,这种情况发生在你访问控件/窗体(或其父控件/窗体)的Handle尚未创建的情况下。基本上,你的检查不完整,因此导致了你看到的结果。你需要检查IsHandleCreated,如果它是false,那么无论InvokeRequired返回什么,你都需要使用Invoke/BeginInvoke。[更新]但是:这通常不会很稳健,因为Invoke/BeginInvoke会检查哪个线程创建了Handle以实现其功能...[/更新]只有当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!" );
}

[更新]

因此,为避免这个问题,以下是很重要的:

在除UI线程以外的任何线程中的第一次访问之前,请始终确保Handle已经被创建。

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

[/更新]


IsHandleCreated为false,调用BeginInvoke后会捕获异常。"在窗口句柄被创建之前,无法在控件上调用Invoke或BeginInvoke方法。" - korrawit
已解决!!我的UI线程没有被创建。我只是在调用这个函数之前加了一些延迟,现在它可以工作了! - korrawit

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接