我的 InvokeRequied #2 有什么问题吗?

发布于 2024-12-28 03:48:07 字数 287 浏览 0 评论 0原文

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

我遵循了他推荐的答案但我发现了一个新问题。

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

我的代码有什么问题?

如何解决这个问题?

在此处输入图像描述

The first topic is What wrong with my InvokeRequied

I followed the answer that he recommended it to me but I found a new problem.

The result of below picture is cross thread exception.

What is wrong with my code ?

How to solve this problem ?

enter image description here

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

寒冷纷飞旳雪 2025-01-04 03:48:07

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

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

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

[更新]
但是
这通常无法正常工作,因为 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 你只需要引用 control .Handle 在 UI 线程中强制创建它 - 在您的代码中,这必须在您第一次从非 UI 线程的任何线程访问该控件/表单之前发生。

[/更新]

According to MSDN InvokeRequired can return false even in cases where InvokeRequired should be true - namely in the case that you access InvokeRequired before the Handle of that control/form (or a parent of it) has been created.

Basically your check is incomplete which leads to the result you see.

You need to check IsHandleCreated - if that is false then you would need to use Invoke/BeginInvoke regardless of what InvokeRequired returns.

[UPDATE]
BUT:
This usually won't work robustly since Invoke/BeginInvoke check which thread created Handle to do their magic...
[/UPDATE]

Only if IsHandleCreated is true you act based on what InvokeRequired returns - something along the lines of:

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]

Thus the following is important to avoid this problem

Always make sure that the Handle is already created BEFORE the first access on a thread other than the UI thread.

According to MSDN you just need to reference control.Handle in the UI thread to force it being created - in your code this must happen BEFORE the very first time you access that control/form from any thread that is not the UI thread.

[/UPDATE]

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文