BackgroundWorker and foreach loop
I have to process a loop with backgroundworkers.
Before I start a new loop iteration I need to wait until the provious backgroundworker has finished.
A while loop inside my foreach loop with isbusy flag doesn's seem like a good idea to me.
How should I design this loop so it waits for the bg-worker to end before iterating the loop
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, RunWorkerCompletedEve开发者_StackOverflowntArgs 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!";
}
}
You're using the backgroundworker wrong. Pass the entire list to the background worker and run the foreach loop there.
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;
}
}
}
The basic idea would be to move the foreach into the DoWork method. That could make use of cancellation (it does not seem very effective now).
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) ...
....
}
}
精彩评论