更新的答案:
等待直到完成许多不同任务的真正方法是需要异步等待而不是后台工作.
#
我知道关于backgroundworker的讨论很多,但是我一直在搜寻中,找不到答案.
这是我的代码示例(基本逻辑,实际代码更长),我想知道是否有解决此问题的方法:
BackgroundWorker MCIATS1Worker = new BackgroundWorker();
private AutoResetEvent _MCIATS1WorkerResetEvent = new AutoResetEvent(false);
public MainWindow()
{
InitializeComponent();
MCIATS1Worker = new BackgroundWorker();
MCIATS1Worker.DoWork += new DoWorkEventHandler(MCIATS1Worker_DoWork);
MCIATS1Worker.WorkerReportsProgress = true;
MCIATS1Worker.WorkerSupportsCancellation = true;
MCIATS1Worker.RunWorkerCompleted += new RunWorkerCompletedEventHandler(MCIATS1_RunWorkerCompleted);
for (int i = 1; i <= 10; i++)
{
//some code
MCIATS1Worker.RunWorkerAsync();
_MCIATS1WorkerResetEvent.WaitOne();
}
}
DoWork和Runworker已完成
void MCIATS1Worker_DoWork(object sender, DoWorkEventArgs e)
{
//do something here
}
void MCIATS1_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
MessageBox.Show("hello world");
_MCIATS1WorkerResetEvent.Set();
}
由于某些原因,直到循环结束,才会触发MCIATS1_RunWorkerCompleted.显然,WaitOne正在保持循环.
这是我的问题
为什么当工人实际完成工作时不会触发RunWorkerCompleted?
谢谢.
###更新的解决方案
这是正确的方法.
private async void WhateverFunction()
{
await Task.WhenAll(MCIATS1WorkerDoWorkAsync(param),...other tasks);
}
private Task MCIATS1WorkerDoWorkAsync(bkgWorkParameter param)
{
return Task.Run(() =>
{
//Do whatever
});
}
解决方法:
根据MCIATS1Worker_DoWork方法的工作方式,可以考虑使用async-await方法,这会使代码更简洁.
private async Task MCIATS1WorkerDoWorkAsync()
{
await Task.Delay(1000) // do something asynchronously for 1 second
}
private async void MainWindow_Load(object sender, EventArgs e)
{
for (int i = 1; i <= 10; i++)
{
//some code
await MCIATS1WorkerDoWorkAsync();
MessageBox.Show("hello world");
}
}
消息框将每1秒显示10次.仅在MCIATS1WorkerDoWorkAsync方法成功完成后,await关键字才会继续循环.
使用async-await,您的表单将保持响应状态,并且如果DoWork方法执行某些IO操作,则您将不会启动另一个线程(如BackgroundWorker那样),并且整个执行将在一个线程上进行.