Swiftorial Logo
Home
Swift Lessons
Matchups
CodeSnaps
Tutorials
Career
Resources

Cancellation Tokens in C#

Introduction to Cancellation Tokens

Asynchronous programming in C# often involves long-running operations that might need to be canceled. This is where Cancellation Tokens come into play. Cancellation tokens allow cooperative cancellation between threads, tasks, or other asynchronous operations.

Creating a Cancellation Token

To create a cancellation token, you need a CancellationTokenSource. The Token property of this source gives you the CancellationToken:

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

Using Cancellation Tokens in Asynchronous Methods

To use a cancellation token in an asynchronous method, you need to pass it as an argument. Here is an example using Task.Run:

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

Task.Run(() =>
{
    for (int i = 0; i < 10; i++)
    {
        if (token.IsCancellationRequested)
        {
            Console.WriteLine("Task was cancelled.");
            return;
        }
        Console.WriteLine($"Task iteration {i}");
        Thread.Sleep(1000); // Simulate work
    }
}, token);
                

Canceling a Task

To cancel a task, you call the Cancel method on the CancellationTokenSource:

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

Task task = Task.Run(() =>
{
    for (int i = 0; i < 10; i++)
    {
        if (token.IsCancellationRequested)
        {
            Console.WriteLine("Task was cancelled.");
            return;
        }
        Console.WriteLine($"Task iteration {i}");
        Thread.Sleep(1000); // Simulate work
    }
}, token);

// Cancel the task after 3 seconds
Thread.Sleep(3000);
cts.Cancel();
                

Handling OperationCanceledException

When a task is canceled, it throws an OperationCanceledException. You can handle this exception to perform cleanup or other actions:

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

Task task = Task.Run(() =>
{
    try
    {
        for (int i = 0; i < 10; i++)
        {
            token.ThrowIfCancellationRequested();
            Console.WriteLine($"Task iteration {i}");
            Thread.Sleep(1000); // Simulate work
        }
    }
    catch (OperationCanceledException)
    {
        Console.WriteLine("Task was cancelled.");
    }
}, token);

// Cancel the task after 3 seconds
Thread.Sleep(3000);
cts.Cancel();
                

Combining Multiple Cancellation Tokens

You can combine multiple cancellation tokens using CancellationTokenSource.CreateLinkedTokenSource:

var cts1 = new CancellationTokenSource();
var cts2 = new CancellationTokenSource();

CancellationTokenSource linkedCts = CancellationTokenSource.CreateLinkedTokenSource(cts1.Token, cts2.Token);

CancellationToken token = linkedCts.Token;

Task task = Task.Run(() =>
{
    try
    {
        for (int i = 0; i < 10; i++)
        {
            token.ThrowIfCancellationRequested();
            Console.WriteLine($"Task iteration {i}");
            Thread.Sleep(1000); // Simulate work
        }
    }
    catch (OperationCanceledException)
    {
        Console.WriteLine("Task was cancelled.");
    }
}, token);

// Cancel the task using either of the original tokens
Thread.Sleep(3000);
cts1.Cancel();
                

Best Practices

When using cancellation tokens, consider the following best practices:

  • Always check for cancellation in long-running tasks.
  • Use ThrowIfCancellationRequested to throw an OperationCanceledException.
  • Avoid swallowing OperationCanceledException unless you have a good reason.
  • Always clean up resources in the catch block.

Conclusion

Cancellation tokens are a powerful tool in C# for managing long-running and asynchronous tasks. They allow for graceful and cooperative cancellation, enabling more responsive and robust applications. By following best practices and using the techniques outlined in this tutorial, you can effectively manage task cancellation in your own applications.