第一个话题是What wrong with my InvokeRequied

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

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

我的代码有什么问题?

如何解决这个问题呢 ?

最佳答案

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

基本上你的支票是不完整的,这导致你看到的结果。

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

[更新]
但是 :
这通常不会有效地工作,因为 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 线程的任何线程访问该控件/表单之前发生。

[/更新]

关于c# - 我的 InvokeRequired #2 有什么问题?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/8946590/

10-10 09:47