首先,我还是初学者,所以如果你有耐心,我会很感激:)
我今天一直在为此苦苦挣扎。
问题是,我想要经营三个不同的背景工作者。但是我想等到一个人完成下一个的运行,依此类推。
每个背景工作者都需要时间来完成。长话短说,问题是,我使用WaitOne(),所以每当前一个背景工作者告诉我它完成后,我就可以开始运行新的,但是UI线程一直在冻结,直到三个后台工作者完成
我正在设置一个不同的AutoResetEvent,它负责整个等待和运行的事情。
以下是代码:
AutoResetEvent _resetRIEvent = new AutoResetEvent(false);
AutoResetEvent _resetHEvent = new AutoResetEvent(false);
AutoResetEvent _resetSEvent = new AutoResetEvent(false);
await Task.Run(() => bgwTestResInd.RunWorkerAsync());
_resetRIEvent.WaitOne();
await Task.Run(() => bgwTestHipot.RunWorkerAsync());
_resetHEvent.WaitOne();
await Task.Run(() => bgwTestSurge.RunWorkerAsync());
_resetSEvent.WaitOne();
MessageBox.Show("Im done for real.");
此外,是否可以这样做?
private void bgwTestResInd_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
_resetRIEvent.Set();
}
private void bgwTestHipot_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
_resetHEvent.Set();
}
private void bgwTestSurge_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
_resetSEvent.Set();
}
答案 0 :(得分:5)
不是创建后台工作人员,然后使用人工混合的任务和同步原语来在不同时间启动工作人员,而是从头到尾使用TPL完成整个工作:
await Task.Run(() => TheWorkThatTheFirstBGWWasDoing());
await Task.Run(() => TheWorkThatTheSecondBGWWasDoing());
await Task.Run(() => TheWorkThatTheThirdBGWWasDoing());
或者,如果所有操作都是CPU绑定工作,您只需使用一次Task.Run
调用:
await Task.Run(() =>
{
TheWorkThatTheFirstBGWWasDoing());
TheWorkThatTheSecondBGWWasDoing());
TheWorkThatTheThirdBGWWasDoing());
});
完成。
如果你真的必须使用后台工作者(没有充分理由,但无论如何),那么你需要做的就是在已完成的处理程序中调用RunWorkerAsync
它需要等待的BGW,或者更好的是,只有一个BGW完成第一个工作,然后完成第二个工作需要做的工作,然后完成第三个需要的工作要做。
答案 1 :(得分:-1)
如果您仍想坚持您的计划,那么这里有代码
class Program
{
static void Main(string[] args)
{
var test=new Test();
test.Run();
Console.ReadKey();
}
private class Test
{
AutoResetEvent _resetRIEvent = new AutoResetEvent(false);
AutoResetEvent _resetHEvent = new AutoResetEvent(false);
AutoResetEvent _resetSEvent = new AutoResetEvent(false);
private BackgroundWorker bgwTestResInd = new BackgroundWorker();
private BackgroundWorker bgwTestHipot=new BackgroundWorker();
private BackgroundWorker bgwTestSurge=new BackgroundWorker();
public async void Run()
{
bgwTestResInd.DoWork += BgwTestResInd_DoWork;
bgwTestHipot.DoWork += BgwTestHipot_DoWork;
bgwTestSurge.DoWork += BgwTestSurge_DoWork;
await Task.Run(() => bgwTestResInd.RunWorkerAsync());
_resetRIEvent.WaitOne();
await Task.Run(() => bgwTestHipot.RunWorkerAsync());
_resetHEvent.WaitOne();
await Task.Run(() => bgwTestSurge.RunWorkerAsync());
_resetSEvent.WaitOne();
Console.Write("Done");
}
private void BgwTestHipot_DoWork(object sender, DoWorkEventArgs e)
{
Console.WriteLine("BgwTestHipot done..");
_resetHEvent.Set();
}
private void BgwTestSurge_DoWork(object sender, DoWorkEventArgs e)
{
Console.WriteLine("BgwTestSurge done..");
_resetSEvent.Set();
}
private void BgwTestResInd_DoWork(object sender, DoWorkEventArgs e)
{
Console.WriteLine("BgwTestResInd done..");
_resetRIEvent.Set();
}
}
}
只需将代码添加到DoWork方法中,它们将按照重置AutoResetEvents的顺序运行