How To Start And Stop A Continuously Running Background Worker Using A Button

我与影子孤独终老i 提交于 2019-11-26 14:38:12

问题


Let's say I have a background worker like this:

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

How can I make this background worker start and stop using a button on a WinForm?


回答1:


This is how to do it (link to answer below)




回答2:


Maybe you can use a manualresetevent like this, I didn't debug this but worth a shot. If it works you won't be having the thread spin its wheels while it's waiting

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();
}



回答3:


Use the CancelAsync method.

backgroundworker1.CancelAsync();

In your loop inside the worker thread.

if (backgroundWorker.CancellationPending) return;

This doesn't happen immediately.




回答4:


By stop do you really mean stop or do you mean pause? If you mean stop, then this is a piece of cake. Create a button click event handler for the button you want to be responsible for starting the background worker and a button click event handler for the one responsible for stopping it. On your start button, make a call to the background worker method that fires the do_work event. Something like this:

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

On your stop button, make a call to the method that sets the background worker's CancellationPending to true, like this:

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

Now don't forget to check for the CancelationPending flag inside your background worker's doWork. Something like this:

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

And your doWork method:

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

I hope this can steer you in the right direction. Some further readings:

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

http://msdn.microsoft.com/en-us/library/system.componentmodel.backgroundworker.aspx

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




回答5:


I haven't tested this, I have code somewhere that I'll have to see exactly what I did, but something like this is an adaptation of Fredrik's answer:

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;
]

More complete example of this pattern here:

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



来源:https://stackoverflow.com/questions/3065700/how-to-start-and-stop-a-continuously-running-background-worker-using-a-button

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!