是否可以顺序启动后台工作者?

Is it possible to start background workers sequentially?

我想按顺序使用 3 个后台 worker。

第一个应该做一个工作,更新 UI 并启动第二个后台工作者,它做同样的事情,然后启动最后一个。这应该仅在再次单击按钮时重复。这样的行为有可能获得吗?

public Form1()
{
     InitializeComponent();
     Bw1= = new BackgroundWorker();
     Bw2= = new BackgroundWorker();
     Bw3= = new BackgroundWorker();
     Bw1.DoWork += new DoWorkEventHandler(Bw1_DoWork);
     Bw1.ProgressChanged += new ProgressChangedEventHandler
                    (Bw1_ProgressChanged);
     Bw1.RunWorkerCompleted += new RunWorkerCompletedEventHandler
                    (Bw1_RunWorkerCompleted);
     Bw1.WorkerReportsProgress = true;
     Bw1.WorkerSupportsCancellation = true;
            ...
     Bw3.DoWork += new DoWorkEventHandler(Bw3_DoWork);
     Bw3.ProgressChanged += new ProgressChangedEventHandler
                    (Bw3_ProgressChanged);
     Bw3.RunWorkerCompleted += new RunWorkerCompletedEventHandler
                    (Bw3_RunWorkerCompleted);
     Bw3.WorkerReportsProgress = true;
     Bw3.WorkerSupportsCancellation = true;

}

private void btnStartAsyncOperation_Click(object sender, EventArgs e)
{

     btnStartAsyncOperation.Enabled = false;
     btnCancel.Enabled = true;
     // Kickoff the worker thread to begin its DoWork function.
     BW1.RunWorkerAsync();
}

//THE DO WORK PART
//UPDATE UI
//tHEN

void BW1_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
    STOP BW1;
    BW2.RUN();
}
        ...
    //Until BW 3 completes and here this should stop until next click

后台的原因不清楚

但是,您可以执行以下操作(假设没有合法的 async IO 工作 ,并且这些 任务 不不需要来自非 线程池线程 的 运行。

注意 :如果有合法的 async IO 工作,则不需要 wrap/offload到 Task 并且只使用 await)

优点是:

  • 它是顺序的
  • 因子更简单(自由度更小)
  • 更容易阅读
  • 它使用异步等待模式(并释放消息泵/UI线程)
  • 并将与 UI 更新配合使用

例子

private async void btnStartAsyncOperation_Click(object sender, EventArgs e)
{

   try
   {

      await Task.Run(() => FirstTask1());

      // update the ui

      await Task.Run(() => FirstTask2());

      // update the ui

      await Task.Run(() => FirstTask3());

      // update the ui

   }
   catch (Exception exception)
   {
       // make sure you catch or do something with exception
   }
}

注意:因为这是一个eventasync void是合适的,你需要确定你处理你的异常(因为这是未观察到的)。您可能还想防止双击。