2011-01-21 74 views

回答

7

BackgroundWorker依赖于设置的当前SynchronizationContext来运行。它的目的和专门用于处理UI代码。

因为没有UI同步问题,所以在自我管理线程的服务中通常会更好。使用线程API(或.NET 4任务API)是一个更好的选择。

+0

谢谢你,里德。我读过它应该只用于UI代码,我从来没有在服务中使用它,但我们在办公室有一些“危机”,有些人声称“它正在工作多年”,而且那种事情。我想就这件事给他们一些独立的看法。 – 2011-01-21 20:11:39

1

我在windows服务中多次使用BackgroundWorker,没有任何不良影响。尽管使用SynchronizationContext可能是不必要的,但我没有注意到它会导致问题或性能不佳。

2

嗯,在服务中使用BGW是好的,它只是没有做任何特别有用的事情。其存在的原因是它能够在特定线程上引发ProgressChanged和RunWorkerCompleted事件。获取代码在特定的线程上运行是一件非常不平凡的事情。在执行代码时,不能简单地将调用注入到线程中。这会导致可怕的重入问题。在注入代码不会导致麻烦的状态下,线程必须是“空闲”的。

让一个线程处于空闲状态是一个相当不自然的情况。你使用线程运行的代码,而不是让他们无所事事地转动它的高跟鞋。然而,这是UI线程工作的方式。它将99%的时间花费在消息循环中,等待Windows告诉它做些什么。按钮点击,绘画请求,键盘按下,这样的事情。它在消息循环内部时,实际上是空闲的。非常好的时间来执行注入的代码。

这是什么Winforms的Control.Begin/Invoke和WPF的Dispatcher.Begin/Invoke做。他们将一个委托放入一个队列中,队列被清空,并由消息循环执行委托目标。 WindowsFormsSynchronizationContext和DispatcherSynchronizationContext类是使用它们的同步提供程序。 Winforms和WPF用它们的一个实例替换SynchronizationContext.Current。而后者又被BGW用于提升事件。这使得它们在UI线程上运行。它允许您从工作线程更新非线程安全的用户界面组件。

您可能看到这是标题,服务不使用。默认的同步提供程序不会同步任何内容。它只是使用一个线程池线程来调用Send或Post回调。在服务中使用BGW时会发生什么情况。现在这些事件实际上毫无意义。您可以让DoWork处理程序直接调用事件处理方法。毕竟,DoWork运行的线程也是另一个线程池线程。

好吧,没有真正的伤害,除了让它慢得多。