c# - 为什么不能从 backgroundworker 访问 UI 组件?

标签 c# .net user-interface backgroundworker

线程都共享资源。这就是多线程操作的全部问题。

MSDN说:

You must be careful not to manipulate any user-interface objects in your DoWork event >handler. Instead, communicate to the user interface through the ProgressChanged and RunWorkerCompleted events.

BackgroundWorker events are not marshaled across AppDomain boundaries. Do not use a BackgroundWorker component to perform multithreaded operations in more than one AppDomain.

然而,当我使用 backgroundworker 时,并不是我需要小心不要操作任何 UI 对象,而是如果我尝试从 DOWork 事件访问 UI 组件,那是不能的。代码可以编译,但是当 DoWork 的代码运行时,出现错误:

Cross-thread operation not valid: Control 'utAlerts' accessed from a thread other than the thread it was created on.

MSDN 没有说明这是如何完成的或为什么这样做。后台 worker 是否装饰有一些阻止这种情况的属性?这是如何实现的?

最佳答案

如果您的处理程序是 UI 类中的实例方法,则您应该有权访问该类的成员。

it's that my app won't even compile if I try to access the UI components from the DOWork event.

只有当您的 DoWork 处理程序是静态的或位于与 UI 组件不同的类中时,才会发生这种情况。在这种情况下,您可能无法访问它们,因为它们对您不可见。


编辑:

BackgroundWorker 旨在执行与您的用户界面无关的“工作”。您不能在 UI 线程以外的任何线程上更改用户界面元素,因为用户界面元素往往具有线程关联性。这实际上与 BackgroundWorker 无关,而与线程和用户界面元素有关。

BW 旨在通过为您提供自动编码回 UI 线程的进度和完成事件来解决此问题,从而允许您在那里更改 UI 元素。但是,您始终可以通过 Windows 窗体中的 Control.Invoke 或 WPF 中的 Dispatcher.Invoke 自己直接执行此操作。

至于它是如何工作的——这取决于你使用的是什么框架。例如,在 Windows 窗体中,每个 Control(它是所有 UI 元素的基类)都有一个 Handle,并且该 Handle 在内部是一个 native 窗口句柄。此句柄用于 check the window's Thread ID针对当前线程 ID。这允许在不存储额外变量的情况下进行检查。

关于c# - 为什么不能从 backgroundworker 访问 UI 组件?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5599164/

相关文章:

c# - System.ObjectDisposeException。处理流编写器的正确方法是什么?

c# - .Net 的 LINQ 中存在错误,或者我遗漏了什么?

c# - 请求越多意味着从缓存对象中读取的速度越慢?

xaml - 未设置 UWP PersonPicture 控件背景

java边框图形用户界面

c# - 为 C# 项目自动生成所有内联 XML 文档

c# - 组合单词并从多个文本框生成变体

c# - IDE0059 将值不必要地分配给 'i'

iphone - 如何使用 iphone "maps"应用程序中的设置制作第二层 View

c# - 为什么 kendo Grid 不生成任何 html 输出并且没有服务器端/客户端错误?