我知道BackgroundWorker不应该在Windows Services中使用,但是谁能有一个很好的在线参考来解释为什么?
发布于 2011-01-22 04:09:27
BackgroundWorker依赖于当前设置的SynchronizationContext才能正常工作。它实际上是专门为处理UI代码而设计的。
在服务中自我管理线程通常更好,因为没有UI同步问题。在这里,使用线程API (或.NET 4任务API)是一个更好的选择。
发布于 2011-01-22 06:20:57
好吧,在服务中使用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的线程也只是另一个线程池线程。
好吧,除了让它变得更慢之外,并没有造成什么真正的伤害。
发布于 2011-01-22 04:09:12
我在windows服务中多次使用BackgroundWorker,没有任何不良影响。虽然它对SynchronizationContext的使用可能是不必要的,但我没有观察到它会造成问题或性能低下。
https://stackoverflow.com/questions/4763276
复制相似问题