2017-01-17 3 views
1

Прежде всего, я все еще новичок, поэтому я был бы признателен, если бы у вас было какое-то терпение :)Как подождать, когда BackgroundWorker закончит выполнение другого BackgroundWorker (C#)?

Я сегодня так сильно почесываю голову.

Дело в том, что я хочу запустить трех разных фоновых работников. Но я хотел бы подождать, пока вы закончите, чтобы запустить следующий, и так далее.

Для каждого рабочего стола требуется время для завершения. Короче говоря, я использую WaitOne(), поэтому всякий раз, когда предыдущий фоновый работник говорит мне, что это сделано, я мог бы запустить новый, но поток пользовательского интерфейса замерзает, пока не закончатся три фоновых работника.

Я настраиваю другой 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()); 

Или, если все операции являются ЦП работы, вы можете просто использовать один вызов Task.Run:

await Task.Run(() => 
{ 
    TheWorkThatTheFirstBGWWasDoing()); 
    TheWorkThatTheSecondBGWWasDoing()); 
    TheWorkThatTheThirdBGWWasDoing()); 
}); 

Done.

Если вы действительно должны использовать фоновую работник (который не существует никакой реальной веская причина, но в любом случае), то все, что вам нужно сделать, это вызов 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

Это не исправление проблемы, которую задает вопрос, который является блокировкой пользовательского интерфейса. – Servy

Смежные вопросы