线程需要使用Invoke方法来访问UI控件,但BackGroundworker不需要。为什么?

时间:2014-10-11 22:16:11

标签: c# multithreading backgroundworker difference

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

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

2 个答案:

答案 0 :(得分:2)

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

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

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

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

答案 1 :(得分:-1)

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

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

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