Запустите BackGroundWorker в RunWorkerCompleted WinForms .net - PullRequest
0 голосов
/ 04 февраля 2012

Я бы знал, если это "опасно", запустите Backgrounworker2 в RunWorkerComplete1 следующим образом:

public void backgroundworker1RunComplete (Object sender , RunworkerCompleteEvent e)
{
    Backgroundworker2.runAsync();
}

Могут ли быть какие-либо тупики, различные проблемы и т. Д.? Потому что, может быть, у меня есть только 2 альтернативы:

Запуск асинхронного Backgrounworker2 в RunComplete1 или Использование события ManualReset , где я сбрасываюсь при вводе в BackGroundWorker DoWork1 и я устанавливаю () в WorkerComplete1

Номер 1)

  private void BackgroundWorker1RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
  {
       backgroundWorker2.RunAsync();
  }

Номер 2)

 private void BackgroundWorker1RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
  {
       manualReset.Set();  
  }

 private void BackGrounWorker2DoWork(Object sender , DoWorkEventArgs e)
 {
   manualReset.WaitOne();
  //Do Stuff
 }

1 Ответ

0 голосов
/ 04 февраля 2012

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

Вам просто нужно убедиться, что вы знаете, что вы (и ваши фоновые потоки) делаете, а что не должны делать:

  • Makeубедитесь, что нет возможных тупиков, в которых оба BGW ожидают завершения другого.В этом случае BGW1 запускает BGW2 (который не был запущен) и, кажется, будет выполнен после этого, так что это маловероятно.Однако, если оба запускаются в одно и то же время и ждут завершения другого в любой заданной точке или получают блокировки на разных объектах, оба из которых необходимы обоим BGW, могут возникнуть проблемы.

  • Никогда не пытайтесь напрямую получать или устанавливать значения свойств / полей или вызывать методы в форме из BGW.Если вы должны сделать это, используйте Control.Invoke или Control.BeginInvoke.Вы можете избежать необходимости узнавать разницу с помощью простого метода расширения или двух.

Вот этот метод расширения (кажется, это ошибка в форматере; невозможно поместить блок кода всередина списка):

public static void InvokeIfNecessary(this Control ctrl, Action action)
{
    if(ctrl.InvokeRequired)
    {
       ctrl.Invoke((MethodInvoker)action);
       return;
    }

    action();
}

Вы можете создать другие варианты для получения или возврата значений, но при разумном использовании внешних замыканий вы можете использовать это практически для всего.

  • Не забудьте дождаться или отменить BGW при закрытии содержащей их Формы.Это может потребовать, чтобы вы структурировали метод doWork (и долгосрочные методы, которые он вызывает напрямую), чтобы знать, нужно ли и когда выходить при сигнале извне.
...