2017-01-17 89 views
1

首先,我还是一个初学者,所以我会很感激,如果你可以有一定的耐心:)如何等待BackgroundWorker完成运行另一个BackgroundWorker(C#)?

我一直在抓我的脑袋,今天这么辛苦。

事情是,我想运行三个不同的背景工作者。但是我想等到一个人完成后才能开始下一个,等等。

每个背景工作者都需要时间完成。长话短说,事情是,我使用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(); 
} 
+1

序列为什么你在运行如果你能够使用任务,可以使用BGW吗? – Servy

+0

我其实是一个初学者程序员。我真的不知道哪条路更好。 – dgls61

回答

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能够完成第一个人所做的工作,然后完成第二个人需要完成的工作,然后完成第三个人需要完成的工作。

+0

谢谢Servy。我仍然是初学者,所以在选择做某些事情的方式方面仍然存在一些问题。 – dgls61

-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

+0

这不能解决问题所带来的问题,即UI被阻止。 – Servy

相关问题