How to safely stop a thread in C#?

A thumbnail showing C# threading code.

Stop a thread in C#

Thread.Abort is obsolete. Instead, use a cancelation token to stop a thread.

To stop a thread in C#:

  1. Create a token source new CancellationTokenSource();.
  2. Pass the cancelation token to your method.
  3. Check the status of the cancelation token: IsCancellationRequested.
  4. If the caller requested cancelation, terminate the operation.
  5. Dispose of the cancelation token source.

Here's the full code of how to stop a thread:

using System; 
using System.Threading;

CancellationTokenSource tokenSource = new(); // Create a token source.
Thread thread = new(
  () => LongRunningOperation(tokenSource.Token) // Pass the token to the thread you want to stop.


tokenSource.Cancel(); // Request cancellation. 
thread.Join(); // If you want to wait for cancellation, `Join` blocks the calling thread until the thread represented by this instance terminates.
tokenSource.Dispose(); // Dispose the token source.


void LongRunningOperation(CancellationToken token)
    while(!token.IsCancellationRequested) { // Check if the caller requested cancellation. 
        Console.WriteLine("I'm running");

Don't reuse your cancelation tokens. Once you cancel it should be disposed.

Stop vs Abort: C# Thread

The main difference between stopping a thread and aborting it in C# is that stopping a thread is a graceful process that closes out a thread while aborting a thread is a disruptive process.

When we abort a thread, we run into potential resource locks that can cause negative downstream effects in our application. Instead, stopping a thread using a cancellation token is always the preferred solution.

Abort a thread using Thread.Abort

In .NET 5 and later, Microsoft deprecated the Thread.Abort method. If you try to use it, you'll always get a PlatformNotSupportedException exception.

Using Thread.Abort used to be the most popular way to stop threads, but it has always been problematic:

  • When you call Thread.Abort to abort a thread it's hard to know what code has executed before we got ThreadAbortException exception.
  • When you abort the thread, it's difficult to preserve state integrity.
  • When you abort unmanaged code, the runtime marks it ThreadState.AbortRequested but the exception is only thrown when the thread returns to managed code.
Published on
Download Free Software Developer Career Guide

I've used these principles to increase my earnings by 63% in two years. So can you.

Dive into my 7 actionable steps to elevate your career.