为什么不能从后台工作者访问UI组件?

ric*_*ard 2 .net c# user-interface backgroundworker

线程都共享资源.这是围绕多线程操作的整个问题.

MSDN说:

您必须小心不要操作DoWork事件>处理程序中的任何用户界面对象.而是通过ProgressChanged和RunWorkerCompleted事件与用户界面进行通信.

BackgroundWorker事件不是跨AppDomain边界编组的.不要使用BackgroundWorker组件在多个AppDomain中执行多线程操作.

然而,当我使用backgroundworker时,并不是我需要小心不要操纵任何UI对象,如果我尝试从DOWork事件中访问UI组件,那就不行了.代码编译,但是当DoWork的代码运行时,我收到一个错误:

跨线程操作无效:控制从其创建的线程以外的线程访问的"utAlerts".

MSDN没有说明这是怎么做的或为什么.backgroundworker是否装饰了一些阻止这种情况的属性?这是如何完成的?

Ree*_*sey 6

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

如果我尝试从DOWork事件中访问UI组件,那么我的应用程序甚至无法编译.

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


编辑:

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

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

至于它是如何工作的 - 这取决于你正在使用什么框架.例如,在Windows窗体中,每个Control(所有UI元素的基类)都有一个Handle,而Handle在内部是一个本机窗口句柄.此句柄用于根据当前线程ID 检查窗口的线程ID.这允许在不存储额外变量的情况下进行检查.