C# Thread Termination and Thread.Abort()

Best way to terminate a thread

In general you have two options:

  • allow the thread to terminate itself. This covers your first option.

  • terminate the thread externally. This covers your other options.

And that's it. And none of them, in general, can prevent the threads from running for indefinite time after they should (from the programmer's intent point of view) terminate.

The most predictable approach is the first one. If terminating takes too long, try to do the processing in smaller steps to allow checking the termination flag more frequently. Also, note the IsBackground flag which will help with the application being unable to close itself.

The whole problem with the other options is that any code (except for some special cases like finally blocks) can be just interrupted in the middle of its execution, which can lead to some undesired results (e.g. some unmanaged resources not released) - as it is explained in Thread.Abort documentation.

Note that the third approach in the newest versions of .NET framework is equivalent to calling the Abort method on your executing threads, as explained in the documentation:

The threads in domain are terminated using the Abort method, which throws a ThreadAbortException in the thread. Although the thread should terminate promptly, it can continue executing for an unpredictable amount of time in a finally clause.

So it seems better to use Thread.Abort from these two, as it's simpler and more readable.

If the first approach is problematic, and if you are well aware of the type of operations your thread is executing and there is no problem in interrupting them in-between then the "brutal" approach should be fine.

How to use thread.abort()

In case you have to use threads, try this. Otherwise, try cancelAsync like in this link:
https://www.wpf-tutorial.com/misc/cancelling-the-backgroundworker/

     // We will set this true to notify the worker threads return.
private bool shouldAbort;
// when hitting submit set:
shouldAbort = false;
void MethodThatDoesWork()
{
//we should stop if required
if (shouldAbort)
{
state.Stop();
}
//code
}

we must be sure that all threads are terminated when the form is closed.
so we add these controls.

   private void ItemsCopyer_FormClosing(object sender, FormClosingEventArgs e)
{
System.Diagnostics.Process.GetCurrentProcess().Kill();
}

private void btnAbort_Click(object sender, EventArgs e)
{
shouldAbort = true;
btnAbort.Enabled = false;
}

Revisiting Thread.Abort() - is it safe?

Thread.Abort is a lot safer than it used to be for the following reasons.

  • The runtime will defer aborts while execution is in unmanaged code.
  • The abort will allow finally blocks to execute.

However, there is still a problem with exactly when the ThreadAbortException gets injected. Consider this code.

public class Example
{
private DateTime value = DateTime.MinValue;

public void DoSomething()
{
try
{
value = DateTime.UtcNow;
}
finally
{
}
}
}

If this code were running on a 32-bit platform the value variable could be corrupted if Thread.Abort was called and the ThreadAbortException were injected in the middle of the write to value. Since DateTime is 8 bytes the write has to take place using more than one instruction.

It is possible to guard against this by placing critical code in a finally block and by using Constrained Execution Regions, but it would be incredibly difficult to get right for all but the simplest types your define. And even then you cannot just put everything in a finally block.

Stop / abort a class-loop thread, C#

Your code if(myBool == false) {theadDraw.Abort();} isn't working because you're checking this once, immediately after the thread starts. And it isn't ever checked again (threadDate.Start()' isn't a blocking call).

But, NET Framework contains the CancellationToken concept which is used to cancel asynchronous code.

// Step 1, create a cancellation token:
CancellationTokenSource cancel = new CancellationTokenSource();

// Step 2, reference the token from inside your thread
void ThreadStartMethod() {
while (!cancel.IsCancellationRequested) {
// Do work ...
}
}

// Step 3, cancel the token when you need to
private void Form1_KeyDown(object sender, KeyEventArgs e)
{
if (e.KeyCode == Keys.Space)
cancel.Cancel();
}

Note: make sure you re-create the cancellation token whenever you start the thread

How to abort a Task like aborting a Thread (Thread.Abort method)?


  1. You shouldn't use Thread.Abort()
  2. Tasks can be Cancelled but not aborted.

The Thread.Abort() method is (severely) deprecated.

Both Threads and Tasks should cooperate when being stopped, otherwise you run the risk of leaving the system in a unstable/undefined state.

If you do need to run a Process and kill it from the outside, the only safe option is to run it in a separate AppDomain.


This answer is about .net 3.5 and earlier.

Thread-abort handling has been improved since then, a.o. by changing the way finally blocks work.

But Thread.Abort is still a suspect solution that you should always try to avoid.


And in .net Core (.net 5+) Thread.Abort() will now throw a PlatformNotSupportedException .

Kind of underscoring the 'deprecated' point.

How to terminate a thread in C#?

Thread.Abort will "kill" the thread, but this is roughly equivalent to:

Scenario: You want to turn off your computer

Solution: You strap dynamite to your computer, light it, and run.

It's FAR better to trigger an "exit condition", either via CancellationTokenSource.Cancel, setting some (safely accessed) "is running" bool, etc., and calling Thread.Join. This is more like:

Scenario: You want to turn off your computer

Solution: You click start, shut down, and wait until the computer powers down.



Related Topics



Leave a reply



Submit