线程需要使用Invoke方法来访问UI控件,但BackGroundworker没有;t.为什么

本文关键字:控件 BackGroundworker 没有 为什么 UI 访问 Invoke 方法 线程 | 更新日期: 2023-09-27 18:26:13

BackgroundWorker可以直接访问UI控件,而Thread不能,为什么?

BackgroundWorker不是线程吗?如果不是,那是什么?此外,为什么直接访问受到限制?限制直接访问是微软选择的方式还是必须这样做?

线程需要使用Invoke方法来访问UI控件,但BackGroundworker没有;t.为什么

根据MSDN,"BackgroundWorker类允许您在单独的专用线程上运行操作。"

BackgroundWorker实际使用Form.Invoke()将控制切换到主UI线程以报告进度。事实上,BackgroundWorker只是一个辅助类,您可以很容易地自己编写它,它使用第二个线程来完成工作,但随后它切换到主UI线程来访问GUI。

同样来自MSDN:"您可以监听报告操作进度的事件,并在操作完成时发出信号。"这意味着后台操作在一个单独的线程上运行,您不能从该线程访问GUI。但您可以从进度事件访问GUI控件,因为它是在主UI线程上引发的。无论何时在工作线程上调用BackgroundWorker.ReportProgress(),它都会在主线程上引发BackgroundWorker.ProgressChanged事件。

此外,您还会问为什么不能从其他线程访问GUI。这是因为整个Windows GUI子系统不是线程安全的。据我所知,这在其他平台(Windows之外)也很正常,所以这绝对不是微软特有的。这可能是由于历史原因,可能与代码效率有关。(线程安全的GUI会更慢。)但我不能提供任何强大的信息源作为参考。

后台工作程序将像新线程一样抛出跨线程异常。一个后台工作人员只是一种开始新线程的奇特方式。

如果您正在使用ProgressChanged事件,那么您不需要调用它,因为有一些.NET魔术在幕后为您做这件事。

有关后台工作人员的更多信息:http://msdn.microsoft.com/en-us/library/system.componentmodel.backgroundworker(v=vs.100).aspx