2010-04-26 100 views
2

我必須用backgroundworkers處理一個循環。BackgroundWorker和foreach循環

在我開始一個新的循環迭代之前,我需要等到provious backgroundworker完成。

我的foreach循環內有一個while循環,帶有isbusy標誌對我來說似乎不是個好主意。

我應該如何設計這個循環,因此等待BG-工人迭代循環

public void AutoConnect() 
{ 
    string[] HardwareList = new string[] { "d1", "d4", "ds1_2", "ds4_2" }; 
    foreach (string HW in HardwareList) 
    { 
     if (backgroundWorker1.IsBusy != true) 
     { 
      backgroundWorker1.RunWorkerAsync(HW); 
      // Wait here until backgroundWorker1 finished 
     } 
    } 
} 

private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e) 
{ 

    BackgroundWorker worker = sender as BackgroundWorker; 
    string FileName = e.Argument as string; 
    try 
    { 
     if ((worker.CancellationPending == true)) 
     { 
      e.Cancel = true; 
     } 
     else 
     { 
      // Time consuming operation 
      ParseFile(Filename); 
     } 
    } 
    catch { } 
} 

private void backgroundWorker1_ProgressChanged(object sender, ProgressChangedEventArgs e) 
{ 
    label1.Text = e.ProgressPercentage.ToString() + " lines"; 
} 

private void backgroundWorker1_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e) 
{ 
    if(e.Cancelled == true) 
    { 
     //this.tbProgress.Text = "Canceled!"; 
    } 
    else if(!(e.Error == null)) 
    { 
     //this.tbProgress.Text = ("Error: " + e.Error.Message); 
    } 
    else 
    { 
     label1.text = "Done!"; 
    } 
} 
+1

這似乎是你在做什麼挫敗BackgroundWorker的目的。 (除非這個循環在後臺線程上運行,但是由於您是串行操作,所以這不會起到任何作用) – 2010-04-26 19:49:50

+0

爲什麼要異步運行它,如果您只是要等待它完成?爲什麼不只是同步調用方法(通常)? – 2010-04-26 19:50:39

回答

13

您正在使用backgroundworker錯誤。將整個列表傳遞給後臺工作者並在那裏運行foreach循環。

public void AutoConnect() 
{ 
    string[] HardwareList = new string[] { "d1", "d4", "ds1_2", "ds4_2" }; 
    backgroundWorker1.RunWorkerAsync(HardwareList); 
} 

private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e) 
{ 

    BackgroundWorker worker = sender as BackgroundWorker; 
    string[] FileNames = e.Argument as string[]; 
    int i = 0; 

    foreach (string FileName in FileNames) 
    { 
     ParseFile(FileName); 
     worker.ReportProgress(++i); 
     if (worker.CancellationPending) 
     { 
      e.Cancel = true; 
      break; 
     } 
    } 
} 
+1

是的,我根本沒有看到多個BackgroundWorkers的重點。一個似乎就夠了。 – 2010-04-26 19:53:12

4

的基本想法是在foreach移動到DoWork的方法之前結束。這可以利用取消(現在看起來不太有效)。

string[] HardwareList = new string[] { "d1", "d4", "ds1_2", "ds4_2" }; 
backgroundWorker1.RunWorkerAsync(HardwareList); 


private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e) 
{ 
    BackgroundWorker worker = sender as BackgroundWorker; 
    string[] HardwareList = e.Argument as string[]; 

    foreach (string HW in HardwareList) 
    { 
     if (worker.CancellationPending) ... 
     .... 
    } 
}