0
0
CsharpHow-ToBeginner · 4 min read

How to Cancel Async Operation in C# with CancellationToken

To cancel an async operation in C#, use a CancellationToken passed to the async method and call Cancel() on its CancellationTokenSource. The async method should regularly check token.IsCancellationRequested or throw OperationCanceledException to stop execution cleanly.
📐

Syntax

Use a CancellationTokenSource to create a CancellationToken. Pass this token to your async method. Call Cancel() on the source to request cancellation.

  • CancellationTokenSource: Controls cancellation requests.
  • CancellationToken: Passed to async methods to observe cancellation.
  • Cancel(): Signals the cancellation request.
csharp
var cts = new CancellationTokenSource();
CancellationToken token = cts.Token;

async Task MyAsyncMethod(CancellationToken token)
{
    while (!token.IsCancellationRequested)
    {
        // Do work
        await Task.Delay(1000, token);
    }
    token.ThrowIfCancellationRequested();
}

// To cancel:
cts.Cancel();
💻

Example

This example shows a simple async method that counts numbers every second. It stops counting when cancellation is requested.

csharp
using System;
using System.Threading;
using System.Threading.Tasks;

class Program
{
    static async Task CountAsync(CancellationToken token)
    {
        int count = 0;
        try
        {
            while (true)
            {
                token.ThrowIfCancellationRequested();
                Console.WriteLine($"Count: {count++}");
                await Task.Delay(1000, token);
            }
        }
        catch (OperationCanceledException)
        {
            Console.WriteLine("Counting canceled.");
        }
    }

    static async Task Main()
    {
        var cts = new CancellationTokenSource();
        var countingTask = CountAsync(cts.Token);

        // Cancel after 3 seconds
        await Task.Delay(3000);
        cts.Cancel();

        await countingTask;
    }
}
Output
Count: 0 Count: 1 Count: 2 Counting canceled.
⚠️

Common Pitfalls

Common mistakes when cancelling async operations include:

  • Not passing the CancellationToken to async methods or Task.Delay, so cancellation is ignored.
  • Not checking token.IsCancellationRequested or not throwing OperationCanceledException, which prevents clean cancellation.
  • Calling Cancel() but not awaiting the async method, which can cause unobserved exceptions.
csharp
/* Wrong way: ignoring token */
async Task WrongAsync()
{
    await Task.Delay(5000); // No token passed
}

/* Right way: pass token and check it */
async Task RightAsync(CancellationToken token)
{
    await Task.Delay(5000, token);
    token.ThrowIfCancellationRequested();
}
📊

Quick Reference

  • Create CancellationTokenSource to control cancellation.
  • Pass CancellationToken to async methods and cancellable APIs.
  • Check token.IsCancellationRequested or call token.ThrowIfCancellationRequested() inside async code.
  • Call Cancel() on the source to request cancellation.
  • Await the async method to handle cancellation exceptions properly.

Key Takeaways

Use CancellationTokenSource and CancellationToken to enable cancellation in async methods.
Always pass the CancellationToken to cancellable async calls like Task.Delay.
Check for cancellation inside your async method and throw OperationCanceledException for clean exit.
Call Cancel() on the CancellationTokenSource to request cancellation.
Await the async task to properly handle cancellation and exceptions.