BackgroundWorker и цикл foreach - PullRequest
       15

BackgroundWorker и цикл foreach

2 голосов
/ 26 апреля 2010

Я должен обработать цикл с фоновыми работниками.

Перед тем, как начать новую итерацию цикла, мне нужно дождаться окончания работы проворного фонового работника.

Цикл while внутри моего цикла foreach с флагом isbusy не кажется мне хорошей идеей.

Как мне спроектировать этот цикл так, чтобы он ожидал завершения bg-worker перед повторением цикла

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!";
    }
}

Ответы [ 2 ]

12 голосов
/ 26 апреля 2010

Вы используете фонового работника неправильно. Передайте весь список фоновому работнику и запустите там цикл 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;
       }
    }
}
4 голосов
/ 26 апреля 2010

Основная идея заключается в том, чтобы переместить 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) ...
        .... 
    }
}
...