How to "kill" background worker completely?

I am writing a windows application that runs a sequence of digital IO actions repeatedly.

This sequence of actions starts when the user click a "START" button, and it is done by a background worker in backgroundWorker1_DoWork().

However, there are occasions when I get the "This backgroundworker is currently busy......." error message.

I am thinking of implementing the following in the code, by using a while loop to "kill" the background worker before starting another sequence of action:

if (backgroundWorker1.IsBusy == true)
{

    backgroundWorker1.CancelAsync();
    while (backgroundWorker1.IsBusy == true)
    {
        backgroundWorker1.CancelAsync();
    }

    backgroundWorker1.Dispose();

}

backgroundWorker1.RunWorkerAsync();

I think my main concern is, will the backgroundWorker1 be "killed" eventually? If it will, will it take a long time to complete it?

Will this coding get me into an infinite loop?


You can use something like this (for more information about aborting managed threads and about ThreadAbortException see "Plumbing the Depths of the ThreadAbortException Using Rotor (Web archive)" by Chris Sells):

public class AbortableBackgroundWorker : BackgroundWorker
{

    private Thread workerThread;

    protected override void OnDoWork(DoWorkEventArgs e)
    {
        workerThread = Thread.CurrentThread;
        try
        {
            base.OnDoWork(e);
        }
        catch (ThreadAbortException)
        {
            e.Cancel = true; //We must set Cancel property to true!
            Thread.ResetAbort(); //Prevents ThreadAbortException propagation
        }
    }

 
    public void Abort()
    {
        if (workerThread != null)
        {
            workerThread.Abort();
            workerThread = null;
        }
    }
}

Usage:

backgroundWorker1 = new AbortableBackgroundWorker();
//...
backgroundWorker1.RunWorkerAsync();

if (backgroundWorker1.IsBusy == true)
{
    backgroundWorker1.Abort();
    backgroundWorker1.Dispose();
}

I'm of the opinion that threads should be responsible for their own resources as much as practicable, including their own lifetime.

It's usually a bad idea to kill threads from outside their scope. Applications that are engineered to pass a message to the thread to shut itself down tend to have far less problems related to multi-threaded behavior.

A thread should monitor for said message, which can be as simple as a boolean set by another thread and read by that monitoring thread, in a timely fashion and shut itself down cleanly as soon as it can.

That means if it should look for the message:

  • in it's main loop, if any.
  • periodically in any long-running loops.

The thread shutting it down with the message should wait (but don't halt the GUI, of course).

Note that there are other possibilities for threaded environments with specific capabilities such as the case where threads can mark themselves cancellable at will, to allow external killing to be safer.

But it's still usually easier to just architect your application to leave a thread master of its own destiny.


I was having the same problem, I'm not sure if this will help but I'm guessing your background worker has a loop within or it would exit. What you need to do is put your loop within.

Put inside your background worker:

while (backgroundworker1.CancellationPending == false)
{
    //Put your code in here
}

To kill this backgroundworker, you can put in your button:

BackgroundWorker1.CancelAsync()

I hope this helps.