后台工作未在 GUI 线程上完成

发布于 2024-08-03 22:42:20 字数 1246 浏览 3 评论 0原文

我有一个在主线程上启动的后台工作程序,如图所示 替代文本
(来源:developingtrends.co.uk

它执行按预期在工作线程上 替代文本
(来源:developingtrends.co.uk

但是对于出于某种原因,它在工作线程上完成,如果我尝试更新 gui 线程上的任何内容,这会导致我出现问题。 替代文本
(来源:developingtrends.co.uk

我有在测试应用程序上尝试了简化的设置,在此应用程序中,线程确实在主线程上正确结束 替代文本
(来源:developingtrends.co.uk

你可以吗想到这可能发生的任何原因吗?

谢谢罗斯

I have a background worker that is started on the main thread as shown
alt text
(source: developingtrends.co.uk)

It executes on a worker thread as expected
alt text
(source: developingtrends.co.uk)

but for some reason it completes on the worker thread which causes me issues if I try and update anything on the gui thread.
alt text
(source: developingtrends.co.uk)

I have tried a simplified setup on a test app and in this app the thread does end correctly on the main thread
alt text
(source: developingtrends.co.uk)

Can you think of any reason this might have happened?

Thanks

Ross

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

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

发布评论

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

评论(2

遮云壑 2024-08-10 22:42:20

在旧版本的 Windows 窗体中可以看到此行为。即使 BGW 是在主线程上启动的,SynchronizationContext.Current 的值为 null。这个错误在去年的某个时候得到了修复。

来自我的博客:

Windows 窗体只会在创建该线程的第一个 Win32 窗口句柄时安装 WindowsFormsSynchronizationContext。特别是,通过主窗体的构造函数和 Load 事件,SynchronizationContext.Current 为 null。但是,它会在调用 Show 事件时设置。一种常见的解决方法是强制创建 Win32 窗口句柄(通过读取 Handle 属性),这会安装正确的 SynchronizationContext 作为副作用。

幸运的是,这种黑客行为不再是必要的。去年的某个时候,Microsoft 发布了一个更新,修复了 .NET 2.0 Windows Forms 项目中的这个问题。我不确定那是哪个更新。

This behavior was seen in older versions of Windows Forms. Even though the BGW is started on the main thread, the value of SynchronizationContext.Current was null. This bug was fixed sometime in the last year.

From my blog:

Windows Forms would only install the WindowsFormsSynchronizationContext when the first Win32 window handle for that thread was created. In particular, SynchronizationContext.Current was null through the main form's constructor and Load event. It would be set, however, by the time the Show event was invoked. One common workaround was to force the creation of the Win32 window handle (by reading the Handle property), which installed the proper SynchronizationContext as a side-effect.

Fortunately, that hack is no longer necessary. Sometime in the last year, Microsoft released an update that fixes that issue all the way back to .NET 2.0 Windows Forms projects. I'm not sure which update that was.

岛徒 2024-08-10 22:42:20

不知道为什么会发生这种情况。但如果您想处理结果,请尝试以下操作:

    void a_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
    {
        ProcessResult((string) e.Result);
    }

    public delegate void ProcessResultDelegate(string result);
    void ProcessResult(string result)
    {
        if (textBox1.InvokeRequired)
        {
            var d = new ProcessResultDelegate(ProcessResult);
            d.Invoke(result);
        }
        else
        {
            textBox1.Text = result;
        }
    }

No idea why this happeneds. But if you want to process the result try the following:

    void a_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
    {
        ProcessResult((string) e.Result);
    }

    public delegate void ProcessResultDelegate(string result);
    void ProcessResult(string result)
    {
        if (textBox1.InvokeRequired)
        {
            var d = new ProcessResultDelegate(ProcessResult);
            d.Invoke(result);
        }
        else
        {
            textBox1.Text = result;
        }
    }
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文