Как запустить и остановить непрерывно рабочего второстепенного рабочего Используя кнопку

Скажем, у меня есть второстепенный рабочий как это:

private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
        {
             while(true)
             {
                  //Kill zombies
             }
        }

Как я могу заставить этого второстепенного рабочего запустить и прекратить использовать кнопку на WinForm?

6
задан sooprise 17 June 2010 в 21:15
поделиться

5 ответов

Под остановкой вы действительно имеете в виду остановку или паузу? Если вы имеете в виду стоп, то это проще простого. Создайте обработчик события нажатия кнопки для кнопки, которую вы хотите нести ответственность за запуск фонового работника, и обработчик события нажатия кнопки для того, кто отвечает за его остановку. На кнопке запуска вызовите метод фонового рабочего, который запускает событие do_work. Примерно так:

private void startButton_Click(System.Object sender, 
    System.EventArgs e)
{
    // Start the asynchronous operation.
    backgroundWorker1.RunWorkerAsync();
}

На кнопке остановки вызовите метод, который устанавливает для фонового рабочего элемента CancellationPending значение true, например:

private void cancelAsyncButton_Click(System.Object sender, 
    System.EventArgs e)
{   
    // Cancel the asynchronous operation.
    this.backgroundWorker1.CancelAsync();
}

Теперь не забудьте проверить CancelationPending в doWork фонового рабочего. Примерно так:

   private void KillZombies(BackgroundWorker worker, DoWorkEventArgs e)
   {
        while (true)
        {
            if (worker.CancellationPending)
           {   
              e.Cancel = true;
           }
        }
   }

И ваш метод doWork:

private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
        {
             BackgroundWorker worker = sender as BackgroundWorker;
             KillZombies(worker, e);
        }

Я надеюсь, что это может направить вас в правильном направлении. Некоторые дополнительные материалы для чтения:

http://msdn.microsoft.com/en-us/library/b2zk6580 (v = VS.90) .aspx

http://msdn.microsoft.com/en-us/ библиотека / system.componentmodel.backgroundworker.aspx

http://msdn.microsoft.com/en-us/library/waw3xexc.aspx

4
ответ дан 8 December 2019 в 02:40
поделиться

Я не тестировал это, у меня где-то есть код, надо будет посмотреть, что именно я сделал, но что-то вроде этого - адаптация ответа Фредрика:

private bool _performKilling;
private object _lockObject = new object();

private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
{
     while(true)
     {

         if (_performKilling)
         {
             //Kill zombies
         }
         else
         { //We pause until we are woken up so as not to consume cycles
             Monitor.Wait(_lockObject);
         }
     }
}

private void StartKilling()
{
    _performKilling = true;
    Monitor.Pulse(_lockObject);
}

private void StopAllThatKilling()
{
    _performKilling = false;
]

Более полный пример этого паттерна здесь:

https://github.com/AaronLS/CellularAutomataAsNeuralNetwork/blob/fe9e6b950e5e28d2c99350cb8ff3157720555e14/CellLifeGame1/Modeling.cs

0
ответ дан 8 December 2019 в 02:40
поделиться

Используйте метод CancelAsync .

backgroundworker1.CancelAsync();

В вашем цикле внутри рабочего потока.

if (backgroundWorker.CancellationPending) return;

Это происходит не сразу.

8
ответ дан 8 December 2019 в 02:40
поделиться

Может быть, вы можете использовать подобное ручное событие, я не отлаживал это, но попробовать стоит. Если это сработает, вы не будете заставлять поток крутиться в ожидании

ManualResetEvent run = new ManualResetEvent(true);

private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e) 
{ 
     while(run.WaitOne()) 
     { 
         //Kill zombies 
     } 
} 

private void War() 
{ 
    run.Set();
} 

private void Peace() 
{ 
    run.Reset();
}
17
ответ дан 8 December 2019 в 02:40
поделиться
Другие вопросы по тегам:

Похожие вопросы: