1

I am using BackgroundWorker for processing a long running external operation. However the user have option to cancel the background operation. Since my custom BackgroundWorker supports Thread.Abort(), all I am doing is BackgroundWorker.Abort() when user triggers Cancel from main thread.

But the thread is not actually terminating, it is still completing the external process. Is there any way I can terminate a thread instantly.

I do not have control on the external processing, so cannot send any flag for approach like while (checkThreadCancelled){}.

Below is my pseudo code.

Any help?

AbortableBackgroundWorker _bgWorker;

void MainThreadFunc()
{
    _bgWorker = new AbortableBackgroundWorker();
    _bgWorker.DoWork += new DoWorkEventHandler(bg_DoWork);
    _bgWorker.RunWorkerCompleted += new RunWorkerCompletedEventHandler
                    ( bg_RunWorkerCompleted );
    _bgWorker.WorkerSupportsCancellation = true; 
    _bgWorker.RunWorkerAsync();
}

void bg_DoWork()
{
    //Call external dll function for processing
}

void bg_RunWorkerCompleted()
{

   //Process completed code
}

void CancelBgProcess()
{
   if(_bgWorker != null)
      _bgWorker.Abort();
}
Saroj
  • 207
  • 2
  • 5
  • 14

3 Answers3

3

The Abort method relies on worker thread cooperating with it. Ultimately it causes the CLR to throw an exception indicating that the thread is to abort, which the thread is free to deal with as it pleases.

As your worker thread is executing something in a DLL, the CLR isn't in control and therefore it does not have the option to throw an exception.

You have the option of using the Win32 TerminateThread API, but doing so is severe and may or may not lead to corruption within your process. TerminateThread is not really an option that you should ever choose.

Since you cannot modify the library that you are calling, you are left with two options. The first and easiest approach, lower the priority of the background thread and ignore the fact that it continues to run after cancellation.

The second is to launch your background operation in a separate process rather than thread. At which point, you may terminate the entire process if the operation is cancelled. If you go this route, you will need to pick some form of IPC to communicate the input and output parameters of the library.

Tasks and CancellationTokens ultimately will not help you in this situation as you will end up in the same place: executing library code that will not cooperate with you in order to be cancelled.

William
  • 1,867
  • 11
  • 10
1

You don't want to use Thread.Abort, it is typically considered bad practice. There are many questions asked on SO that provide some very good explanations. For example: Timeout Pattern - How bad is Thread.Abort really?

Try looking at Tasks and CancellationTokens. See this MSDN article: http://msdn.microsoft.com/en-us/library/dd997396.aspx

Community
  • 1
  • 1
d.moncada
  • 16,900
  • 5
  • 53
  • 82
0

Try this:

if (_bgWorker.IsBusy)
            {
                _bgWorker.WorkerSupportsCancellation = true;
                //To cancel the Thread if Closing the Application
                //while the Background Thread Worker is Still running on Background.
                _bgWorker.CancelAsync();                   
            }

It will stop the current thread process and will cancel the ongoing operation on that thread. May be it helps you

Vishal
  • 604
  • 1
  • 12
  • 25