How to safely stop a thread in C#?

By Josip Miskovic
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.
Josip Miskovic
About Josip

Josip Miskovic is a software developer at Josip has 10+ years in experience in developing web applications, mobile apps, and games.

Read more posts →
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.