3

第一个主题是我的 InvokeRequied 出了什么问题

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

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

我的代码有什么问题?

如何解决这个问题呢 ?

在此处输入图像描述

4

1 回答 1

10

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

基本上你的检查是不完整的,这会导致你看到的结果。

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

[更新] 但是:这通常不会正常工作,因为Invoke/BeginInvoke检查创建哪个线程Handle来发挥他们的魔力...... [/更新]

仅当您根据返回的IsHandleCreated内容采取行动时-类似于以下内容:trueInvokeRequired

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!" );
}

[更新]

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

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

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

[/更新]

于 2012-01-20T19:17:16.237 回答