C# 如何等待一个BackgroundWorker完成运行另一个BackgroundWorker(C)?
首先,我还是一个初学者,如果您能有耐心,我将不胜感激: 我今天一直在为这事挠头 问题是,我想管理三个不同的后台工作人员。但我想等到一个完成后再运行下一个,以此类推 每个后台工作人员都需要时间来完成。长话短说,问题是,我正在使用WaitOne,所以每当前一个backgroundworker告诉我它已经完成时,我就可以开始运行新的一个,但是UI线程在三个backgroundworker完成之前是冻结的 我正在设置一个不同的AutoResetEvent,它负责整个等待和运行过程 代码如下:C# 如何等待一个BackgroundWorker完成运行另一个BackgroundWorker(C)?,c#,backgroundworker,autoresetevent,waitone,C#,Backgroundworker,Autoresetevent,Waitone,首先,我还是一个初学者,如果您能有耐心,我将不胜感激: 我今天一直在为这事挠头 问题是,我想管理三个不同的后台工作人员。但我想等到一个完成后再运行下一个,以此类推 每个后台工作人员都需要时间来完成。长话短说,问题是,我正在使用WaitOne,所以每当前一个backgroundworker告诉我它已经完成时,我就可以开始运行新的一个,但是UI线程在三个backgroundworker完成之前是冻结的 我正在设置一个不同的AutoResetEvent,它负责整个等待和运行过程 代码如下: AutoR
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();
}
与其创建后台工作人员,然后使用任务和同步原语的人为混合在不同的时间启动工作人员,不如从头到尾使用TPL来完成整个工作:
await Task.Run(() => TheWorkThatTheFirstBGWWasDoing());
await Task.Run(() => TheWorkThatTheSecondBGWWasDoing());
await Task.Run(() => TheWorkThatTheThirdBGWWasDoing());
或者,如果所有操作都是CPU限制的工作,则只需对Task进行一次调用即可。运行:
完成了
如果您确实必须使用后台工作程序,但没有真正好的理由,但无论如何,您需要做的就是在需要等待的BGW的已完成处理程序中调用RunWorkerAsync,或者,更好的是,只需要一个BGW来完成第一个BGW正在做的工作,然后再完成第二个BGW需要做的工作,然后做第三个需要做的工作。与其创建后台工作人员,然后使用人工混合的任务和同步原语在不同的时间启动工作人员,不如从头到尾使用TPL来完成整个工作:
await Task.Run(() => TheWorkThatTheFirstBGWWasDoing());
await Task.Run(() => TheWorkThatTheSecondBGWWasDoing());
await Task.Run(() => TheWorkThatTheThirdBGWWasDoing());
或者,如果所有操作都是CPU限制的工作,则只需对Task进行一次调用即可。运行:
完成了
如果您确实必须使用后台工作程序,但没有真正好的理由,但无论如何,您需要做的就是在需要等待的BGW的已完成处理程序中调用RunWorkerAsync,或者,更好的是,只需要一个BGW来完成第一个BGW正在做的工作,然后再完成第二个BGW需要做的工作,然后做第三个需要做的工作。如果你还想坚持你的计划,这里有代码
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方法中,它们将按照您重置自动重置事件的顺序运行如果您仍然想坚持您的计划,下面是代码
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的顺序运行如果你能够使用任务,为什么还要使用BGW?我实际上是一个初学者。我真的不知道哪条路更好。如果你能使用任务,为什么还要使用BGW呢?我实际上是个初学者。我真的不知道哪条路更好。谢谢你。我还是一个初学者,所以我在选择做一些事情的方法时仍然有一些问题。谢谢你。我还是一个初学者,所以我在选择做一些事情的方式时仍然有一些问题。这不是解决问题,这是UI被阻止的问题。这不是解决问题,这是UI被阻止的问题。