2011-01-21 23 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運行的線程也是另一個線程池線程。

好吧,沒有真正的傷害,除了讓它慢得多。