Cancellationtoken In C# Complete Guide

 Last Update:2025-06-23T00:00:00     .NET School AI Teacher - SELECT ANY TEXT TO EXPLANATION.    8 mins read      Difficulty-Level: beginner

Understanding the Core Concepts of CancellationToken in C#

CancellationToken in C# Overview and Detailed Explanation

Key Components and Concepts

  1. CancellationTokenSource

    • Description: CancellationTokenSource is responsible for the creation and management of a CancellationToken. It provides methods like Cancel() to initiate cancellation and CancelAfter(TimeSpan) to schedule a cancellation after a specified time.
    • Usage: You instantiate a CancellationTokenSource and use its Token property to obtain a CancellationToken that you can pass to tasks, asynchronous methods, or any piece of code that needs to support cancellation.
  2. CancellationToken

    • Description: A CancellationToken is used to communicate a request for cancellation. It contains a IsCancellationRequested property that indicates whether cancellation has been requested. You can also register a callback using the Register method, which will be invoked if cancellation is requested before the token is disposed.
    • Usage: Typically, a CancellationToken is passed as a parameter to long-running methods or tasks that need to be able to respond to cancellation requests.

How Cancellation Works

When a cancellation request is made via a CancellationTokenSource, the CancellationToken associated with it is notified. Tasks and methods monitoring this token can then take appropriate action, such as stopping work, releasing resources, or cleaning up state.

Here's a simple example demonstrating the basics:

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

public class CancellationTokenExample
{
    public static void Main()
    {
        var cts = new CancellationTokenSource();
        var token = cts.Token;

        var task = Task.Run(() =>
        {
            for (int i = 0; i < 100; i++)
            {
                if (token.IsCancellationRequested)
                {
                    Console.WriteLine("Cancellation requested!");
                    token.ThrowIfCancellationRequested(); // Will throw a OperationCanceledException
                }
                Console.WriteLine(i);
                Thread.Sleep(100); // Simulate work
            }
            Console.WriteLine("Task completed successfully.");
        }, token);

        Console.WriteLine("Press 'c' to cancel the task...");
        var input = Console.ReadKey();
        if (input.KeyChar == 'c')
        {
            cts.Cancel();
        }

        try
        {
            task.Wait(); // Wait for task to complete
        }
        catch (AggregateException ae)
        {
            ae.Handle(e =>
            {
                if (e is OperationCanceledException)
                {
                    Console.WriteLine("Task was canceled.");
                    return true;
                }
                return false;
            });
        }
    }
}

Key Points About Cancellation

  • Thread Safety: Operations on CancellationTokenSource and CancellationToken are thread-safe, making it safe to request cancellation from one thread while the work is happening on another.
  • Register Callbacks: You can register multiple callbacks with a CancellationToken to be invoked when cancellation is requested. This allows you to centralize your cleanup logic.
  • Graceful Shutdown: By using CancellationToken, you can ensure that your application can shutdown gracefully, minimizing data loss or corruption.

Commonly Used Methods

  • CancellationTokenSource.Cancel(): Requests cancellation. This method does not block and can be called multiple times.
  • CancellationTokenSource.CancelAfter(TimeSpan delay): Schedules a cancellation request after a specified delay.
  • CancellationToken.Register(Action callback): Registers an action to be called when cancellation is requested.
  • CancellationToken.IsCancellationRequested: Checks if cancellation has been requested.
  • CancellationToken.ThrowsIfCancellationRequested(): Throws an OperationCanceledException if cancellation has been requested.

Usage in Asynchronous Programming

CancellationToken is widely used in modern asynchronous programming models in C#. When working with async and await, a CancellationToken can be passed to asynchronous methods to allow cancellation. Here's an example using HttpClient:

using System;
using System.Net.Http;
using System.Threading;
using System.Threading.Tasks;

public class HttpClientExample
{
    public static async Task Main(string[] args)
    {
        var cts = new CancellationTokenSource();
        var token = cts.Token;

        var client = new HttpClient();

        try
        {
            var response = await client.GetAsync("https://api.github.com/users/dotnet/repos", token);
            Console.WriteLine(response.StatusCode);
        }
        catch (OperationCanceledException)
        {
            Console.WriteLine("Request was cancelled.");
        }

        Console.WriteLine("Press 'c' to cancel the request...");
        var key = Console.ReadKey();
        if (key.KeyChar == 'c')
        {
            cts.Cancel();
        }
    }
}

Best Practices

  • Keep Cancellation Optional: Always provide overloads without a CancellationToken parameter for APIs that might be used in contexts where cancellation is not desired.
  • Handle OperationCanceledException: Properly exception handling with try-catch blocks can help ensure that your application can handle cancellation requests gracefully.
  • Use Register for Cleanup: Consider using Register for cleanup tasks that need to run when cancellation is requested.

Summary

The CancellationToken is a fundamental concept in C# used for managing and responding to cancellation requests in both synchronous and asynchronous operations. By leveraging CancellationTokenSource and CancellationToken, developers can create more robust and flexible applications capable of graceful shutdowns and effective resource management.

Online Code run

🔔 Note: Select your programming language to check or run code at

💻 Run Code Compiler

Step-by-Step Guide: How to Implement CancellationToken in C#

What is CancellationToken?

CancellationToken is a way to signal that a task or operation should be cancelled. It is commonly used for cooperative cancellation, where tasks periodically check whether they should be stopped and then exit gracefully.

Step-by-Step Guide with Examples

Step 1: Setting up a CancellationTokenSource

The CancellationTokenSource is responsible for creating CancellationToken instances and for cancelling them.

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

class Program
{
    static async Task Main(string[] args)
    {
        // Create a CancellationTokenSource
        CancellationTokenSource cancellationTokenSource = new CancellationTokenSource();

        // Optionally, set a cancellation token timeout
        // cancellationTokenSource.CancelAfter(TimeSpan.FromSeconds(5));

        // Create a CancellationToken
        CancellationToken cancellationToken = cancellationTokenSource.Token;

        // Launch the long running task
        Task task = LongRunningTask(cancellationToken);

        // Wait for user input to cancel
        Console.WriteLine("Press 'C' to cancel the task...");
        if (Console.ReadKey().KeyChar == 'C')
        {
            cancellationTokenSource.Cancel();
        }

        // Wait for the task to complete
        try
        {
            await task;
            Console.WriteLine("Task completed successfully.");
        }
        catch (OperationCanceledException)
        {
            Console.WriteLine("Task was cancelled.");
        }
        catch (Exception ex)
        {
            Console.WriteLine($"An error occurred: {ex.Message}");
        }
    }

    static async Task LongRunningTask(CancellationToken cancellationToken)
    {
        for (int i = 0; i < 100; i++)
        {
            // Check if cancellation is requested
            cancellationToken.ThrowIfCancellationRequested();

            // Simulate some work
            Console.WriteLine($"Working... {i + 1}/100");
            await Task.Delay(100);
        }
    }
}

Explanation:

  • CancellationTokenSource: This is used to create a CancellationToken and to request cancellation.
  • CancellationToken: This is passed to the long-running task. The task uses it to check for a cancellation request.
  • Task Delay: This simulates a long-running task.
  • ThrowIfCancellationRequested: This method throws an OperationCanceledException if a cancellation is requested.
  • CancelAfter: Optionally, set a timeout for cancellation.

Step 2: Cancellation with User Input

In the above example, if the user presses 'C', we call cancellationTokenSource.Cancel(); which sends a cancellation request to the task. The task checks for the cancellation request in the loop and throws an OperationCanceledException if it is requested.

Step 3: Handling Multiple Tasks

You can also manage multiple tasks using a single CancellationToken.

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

class Program
{
    static async Task Main(string[] args)
    {
        CancellationTokenSource cancellationTokenSource = new CancellationTokenSource();
        CancellationToken cancellationToken = cancellationTokenSource.Token;

        Task task1 = LongRunningTask("Task1", cancellationToken);
        Task task2 = LongRunningTask("Task2", cancellationToken);

        Console.WriteLine("Press 'C' to cancel all tasks...");
        if (Console.ReadKey().KeyChar == 'C')
        {
            cancellationTokenSource.Cancel();
        }

        try
        {
            await Task.WhenAll(task1, task2);
            Console.WriteLine("All tasks completed successfully.");
        }
        catch (OperationCanceledException)
        {
            Console.WriteLine("One or more tasks were cancelled.");
        }
        catch (Exception ex)
        {
            Console.WriteLine($"An error occurred: {ex.Message}");
        }
    }

    static async Task LongRunningTask(string name, CancellationToken cancellationToken)
    {
        for (int i = 0; i < 10; i++)
        {
            cancellationToken.ThrowIfCancellationRequested();

            Console.WriteLine($"{name} Working... {i + 1}/10");
            await Task.Delay(500);
        }
    }
}

Explanation:

  • Task.WhenAll: This method waits for all of the provided tasks to complete. If a cancellation is requested, it will cancel all tasks.
  • Multiple Tasks: We have two tasks running simultaneously, and they can be cancelled together.

Step 4: Cancellation with Timeouts

You can also use CancellationToken to cancel tasks after a specified time.

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

class Program
{
    static async Task Main(string[] args)
    {
        CancellationTokenSource cancellationTokenSource = new CancellationTokenSource();
        cancellationTokenSource.CancelAfter(TimeSpan.FromSeconds(10)); // Cancel after 10 seconds
        CancellationToken cancellationToken = cancellationTokenSource.Token;

        Task task = LongRunningTask(cancellationToken);

        try
        {
            await task;
            Console.WriteLine("Task completed successfully.");
        }
        catch (OperationCanceledException)
        {
            Console.WriteLine("Task was cancelled due to timeout.");
        }
        catch (Exception ex)
        {
            Console.WriteLine($"An error occurred: {ex.Message}");
        }
    }

    static async Task LongRunningTask(CancellationToken cancellationToken)
    {
        for (int i = 0; i < 100; i++)
        {
            cancellationToken.ThrowIfCancellationRequested();

            Console.WriteLine($"Working... {i + 1}/100");
            await Task.Delay(100);
        }
    }
}

Explanation:

  • CancelAfter: The task will be automatically cancelled after 10 seconds.

Summary

The CancellationToken is a powerful mechanism for cooperative cancellation in C#. It allows you to stop long-running operations gracefully, either manually or after a timeout. By understanding and using CancellationToken, you can make your applications more robust and responsive.

Top 10 Interview Questions & Answers on CancellationToken in C#

Top 10 Questions and Answers about CancellationToken in C#

1. What is CancellationToken in C#?

2. How does CancellationToken work in C#?

Answer: CancellationToken works through a combination of CancellationTokenSource and CancellationToken. A CancellationTokenSource is created, and its Token property is passed to the method that should be cancellable. When cancellation is requested (using CancellationTokenSource.Cancel()), the token's IsCancellationRequested property becomes true. The method regularly checks this property and responds accordingly.

3. When should you use CancellationToken?

Answer: Use CancellationToken in scenarios where you need to be able to cancel long-running or potentially blocking operations gracefully. For example, in long-running data processing, network requests, or any operation that might take an indeterminate amount of time, CancellationToken can help prevent the application from becoming unresponsive or wasting resources.

4. How do you create a CancellationToken?

Answer: A CancellationToken is created from a CancellationTokenSource. Here’s a simple example:

using CancellationTokenSource cts = new();
CancellationToken token = cts.Token;

You can then pass token to methods that support cancellation. To request cancellation, you call cts.Cancel().

5. How can you handle cancellation in a method?

Answer: In your method, you should periodically check if cancellation has been requested using token.IsCancellationRequested. If true, you should clean up and exit the method. Alternatively, use methods that natively support CancellationToken, such as Task.Delay, HttpClient.GetAsync, etc.

async Task ProcessDataAsync(CancellationToken token) {
    for (int i = 0; i < 100; i++) {
        await Task.Delay(100, token);
        if (token.IsCancellationRequested) {
            throw new OperationCanceledException(token);
        }
    }
}

6. Can CancellationToken be re-used after cancellation?

Answer: No, once a CancellationTokenSource is canceled, it remains in the canceled state. If you need multiple independent cancellation tokens, you should create multiple CancellationTokenSources.

7. What happens if a method does not handle CancellationToken?

Answer: If a method does not handle a CancellationToken appropriately, cancellation requests will not affect that method. The method will continue running until completion or until it encounters a cancellation-aware operation that respects the token.

8. How can you combine multiple CancellationToken objects?

Answer: You can combine multiple CancellationToken objects into a single one using CancellationTokenSource.CreateLinkedTokenSource(). This allows you to monitor multiple tokens with a single token.

var cts1 = new CancellationTokenSource();
var cts2 = new CancellationTokenSource();
var combinedToken = CancellationTokenSource.CreateLinkedTokenSource(cts1.Token, cts2.Token).Token;

9. What is the difference between CancellationToken and DisposePattern in C#?

Answer: CancellationToken is a pattern for signaling cancellation requests to operations, while the Dispose pattern (IDisposable) is used to free resources held by objects. Both patterns are about resource management, but CancellationToken is specifically about controlling the lifecycle of tasks, while IDisposable ensures timely cleanup of unmanaged resources.

10. Can CancellationToken be used outside of asynchronous programming?

Answer: Yes, CancellationToken can be used in synchronous methods as well. Although it is more common in asynchronous code, you can use CancellationToken in synchronous methods to check and respond to cancellation requests.

You May Like This Related .NET Topic

Login to post a comment.