是否可以顺序启动后台工作者?
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
}
}
注意:因为这是一个event
和async void
是合适的,你需要确定你处理你的异常(因为这是未观察到的)。您可能还想防止双击。
我想按顺序使用 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
}
}
注意:因为这是一个event
和async void
是合适的,你需要确定你处理你的异常(因为这是未观察到的)。您可能还想防止双击。