[英]RunWorkerAsync close BackgroundWorker on complete
我有一個后台工作程序,需要根據選中的復選框數多次調用它-我已編寫了此背景程序以獲取復選框值並將其放入List
。
List repSelected = new List();
填充它,然后像下面這樣迭代:
foreach (string rep in repSelected)
{
backgroundWorker1.RunWorkerAsync(rep);
backgroundWorker1.RunWorkerCompleted += new RunWorkerCompletedEventHandler(backgroundWorker1_RunWorkerCompleted);
}
異步DoWork代碼如下所示:
BackgroundWorker worker = sender as BackgroundWorker;
string rep = e.Argument.ToString();
if (worker.CancellationPending == true)
{
e.Cancel = true;
}
else
{
DirectoryExists(rep);
ProcessRunner(rep); //Rars some large files - expensive
}
然后,該進程運行WorkerComplete,問題是當該進程返回以進行Worker的下一次迭代時,它崩潰了,說出該Worker處於忙碌狀態-即使該Worker返回了其WorkerCompleted狀態。
如何確保在下一次循環迭代之前關閉線程?
注意:我對包含!backgroundWorker1.IsBusy()
的后台工作器有條件,但是(顯然)這只是跳過了其余的迭代而沒有執行。
如果要按順序處理每個項目,則沒有理由為每個任務使用單獨的后台工作人員。 因此,最好將foreach循環移至DoWork方法中。 但是,如果要處理paralell中的所有項目,則需要為每個項目創建一個后台工作程序。
從MSDN:
如果后台操作已經在運行,則再次調用RunWorkerAsync將引發InvalidOperationException。
因此,您不能使用BackgroundWorker
來維護任務隊列 (並且按順序推送所有任務,而無需等待一個任務完成)。 您對此有不同的解決方案,例如,如果要繼續使用BackgroundWorker
,則可以這樣做:
backgroundWorker1.RunWorkerAsync(repSelected);
然后像下面這樣更改您的DoWork
方法:
BackgroundWorker worker = sender as BackgroundWorker;
foreach (string rep in (IEnumerable<string>)e.Argument)
{
if (worker.CancellationPending == true)
{
e.Cancel = true;
return;
}
else
{
DirectoryExists(rep);
ProcessRunner(rep); //Rars some large files - expensive
}
}
作為替代方案,您可以考慮更改執行此任務的方式,例如,使用System.Threading.Tasks.Task
或ThreadPool
(直接或間接將大多數並行操作排隊到池中)。
您的foreach代碼將立即觸發所有元素的工作。 這就是為什么您會得到例外。
如果要順序啟動工作程序,則只能在啟動時調用RunWorkerAsync一次,然后再為每個WorkerComplete事件調用一次。 但是,為什么不在工作者代碼中進行foreach的處理呢?
BackgroundWorker確實很忙,因為當第一次調用backgroundWorker1.RunWorkerAsync(rep);
,它不等待任何內容,因此第二,第三,...調用立即被調用。
您應該在每次調用時創建BackgroundWorker,這樣就可以了。
您可以雇用parallel.foreach和多個背景工作人員;
Parallel.ForEach(YourListofStrings,
(q) =>
{
BackgroundWorker worker = new BackgroundWorker();
worker.DoWork += new DoWorkEventHandler(worker_DoWork);
worker.RunWorkerCompleted += new RunWorkerCompletedEventHandler(worker_RunWorkerCompleted);
worker.RunWorkerAsync(q);
});
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.