2011-09-13 39 views
23

我是那些偶然的程序員之一,所以我沒有太多關於編程最佳實踐的知識。C#應該創建一個或多個後臺工作者嗎?

我有一個應用程序,當前使用4後臺工作。

所以我宣佈他們:

private BackgroundWorker bw1; 
private BackgroundWorker bw2; 
private BackgroundWorker bw3; 
private BackgroundWorker bw4; 

將它們配置:

bw1 = new BackgroundWorker(); 
bw1.WorkerReportsProgress = true; 
bw1.DoWork += new DoWorkEventHandler(bw1_DoWork); 
bw1.RunWorkerCompleted += new RunWorkerCompletedEventHandler(bw1_RunWorkerCompleted); 
bw1.ProgressChanged += new ProgressChangedEventHandler(bw_ProgressChanged); 

bw2 = new BackgroundWorker(); 
bw2.WorkerReportsProgress = true; 
bw2.DoWork += new DoWorkEventHandler(bw2_DoWork); 
bw2.RunWorkerCompleted += new RunWorkerCompletedEventHandler(bw2_RunWorkerCompleted); 
bw2.ProgressChanged += new ProgressChangedEventHandler(bw_ProgressChanged); 

bw3 = new BackgroundWorker(); 
bw3.WorkerReportsProgress = true; 
bw3.DoWork += new DoWorkEventHandler(bw3_DoWork); 
bw3.RunWorkerCompleted += new RunWorkerCompletedEventHandler(bw3_RunWorkerCompleted); 
bw3.ProgressChanged += new ProgressChangedEventHandler(bw_ProgressChanged); 

bw4 = new BackgroundWorker(); 
bw4.WorkerReportsProgress = true; 
bw4.DoWork += new DoWorkEventHandler(bw4_DoWork); 
bw4.RunWorkerCompleted += new RunWorkerCompletedEventHandler(bw4_RunWorkerCompleted); 
bw4.ProgressChanged += new ProgressChangedEventHandler(bw_ProgressChanged); 

然後我用bw1.RunWorkerAsync(),bw2.RunWorkerAsync(),等等...

事情是我從來沒有同時打電話給他們,他們在不同的地方以非常線性的方式打電話。

所以我的問題是,有更多的「預先配置」的後臺工作人員,或根據我想要做的更改DoWork和RunWorkerCompleted事件嗎?

+5

如果你確實使用了多個後臺工作者,你應該把它們放在'List '中以防止冗餘代碼。這樣,如果再添​​加十個,則不必添加十倍的代碼量。 –

回答

20

從體系結構的角度來看,最好爲每個後臺任務都有一個單獨的後臺工作者,這在邏輯上與該類的另一個任務無關。

0

使用BackgroundWorker進行處理意味着您可以在單獨的線程中進行處理。所以如果你不需要多線程,就不需要單獨的後臺工作人員。如果您在啓動每位員工後等待完成,則只能有一名工人。它也可能會刪除一些代碼重複...

4

通常,使用多個線程是合理的,如果它有助於提高系統上的資源使用效率。對於CPU密集型任務,每個CPU內核一個線程是一個很好的起點。對於IO密集型任務,您當然可以擁有更多的功能。

如果您可以靈活地使用.NET 4,我會考慮Task Parallel Library而不是BackgroundWorker。默認情況下,除了提供更簡單的編程模型之外,它還會爲您做出相對聰明的決定,即有多少線程可以同時運行。

+0

我會看看TPL,我使用的是.NET 4. – Alex

+0

謝謝,我也會盡量了解TPL。 –

0

爲了某些計算目的,您運行工人。如果一次調用的計算被使用或以任何方式依賴於另一次調用,則可以使用多於一名工人,以獲得更好的性能(順便說一下,這也是測量的主題)。如果你只需要完成4個工作,並在單獨的線程中運行它們以便不阻止主UI,那麼一個工作人員是非常好的解決方案。

24

通常我會以完全不同的模式使用後臺工作人員。我不是一開始就包括各自的事件處理程序,而是一次性定義它們,而是在我做需要它們的事情時立即創建它們。

public void SomeEventHandlerMaybe(object sender, EventArgs e) { 
    // do something 

    var bw = new BackgroundWorker(); 
    bw.ReportsProgress = true; 
    bw.DoWork += delegate { 
    // do work. You can use locals from here 
    }; 
    bw.ProgressChanged += delegate { ... }; 
    bw.RunWorkerCompleted += delegate { 
    // do something with the results. 
    }; 
    bw.RunWorkerAsync(); 
} 

就是這樣的。它有一個好處,就是你擁有所有的代碼,可以在一個地方或者在後臺工作者中執行某些操作,而且大致也可以按照正確的順序執行。

+2

我沒有想過在飛行中創建它們,這對我來說是一條很好的道路,謝謝! – Alex

+0

+1 ....這種方法可以節省一些緩存內存:) – Sandy

+0

這種方法是否允許您在DoWork中使用ReportProgress(i)並獲取ProgressChanged委託中的ProgressPercent? – Developr

相關問題