C# tutorials > Asynchronous Programming > Async and Await > What are cancellation tokens (`CancellationToken`)?
What are cancellation tokens (`CancellationToken`)?
In asynchronous programming in C#, CancellationToken
plays a crucial role in managing and controlling the execution of long-running operations. It allows you to gracefully stop or cancel an operation before it completes, which is particularly important in scenarios where resources need to be released or the user has requested the operation to be terminated. Understanding and using CancellationToken
effectively can significantly improve the responsiveness and reliability of your applications.
Introduction to Cancellation Tokens
A CancellationToken
is a structure that represents a request to cancel an operation. It's part of the System.Threading
namespace. It doesn't inherently cancel anything itself; rather, it's a signal that cooperative code can listen for to know when it should stop processing. A CancellationToken
is obtained from a CancellationTokenSource
.
Creating a CancellationTokenSource and CancellationToken
This code demonstrates how to create a CancellationTokenSource
, obtain a CancellationToken
, and use it to monitor for cancellation requests within an asynchronous method (LongRunningOperationAsync
). The cts.Cancel()
method (which isn't called in this specific example but would be called elsewhere in your code, likely triggered by user input or another event) would signal the CancellationToken
. The LongRunningOperationAsync
method periodically checks cancellationToken.IsCancellationRequested
and throws an OperationCanceledException
if cancellation has been requested.
using System;
using System.Threading;
using System.Threading.Tasks;
public class CancellationExample
{
public static async Task Main(string[] args)
{
// Create a CancellationTokenSource
CancellationTokenSource cts = new CancellationTokenSource();
// Get the CancellationToken from the source
CancellationToken token = cts.Token;
try
{
// Start a long-running task
await LongRunningOperationAsync(token);
}
catch (OperationCanceledException)
{
Console.WriteLine("Operation cancelled.");
}
finally
{
cts.Dispose(); // Dispose of the CancellationTokenSource when done
}
Console.WriteLine("Program finished.");
}
public static async Task LongRunningOperationAsync(CancellationToken cancellationToken)
{
for (int i = 0; i < 100; i++)
{
// Check if cancellation has been requested
if (cancellationToken.IsCancellationRequested)
{
cancellationToken.ThrowIfCancellationRequested(); // Throw an exception to stop the operation
}
Console.WriteLine($"Processing: {i}");
await Task.Delay(50, cancellationToken); // Simulate work and check for cancellation
}
Console.WriteLine("Operation completed successfully.");
}
}
Concepts Behind the Snippet
CancellationToken
. It allows you to signal cancellation to the token.CancellationToken
that indicates whether cancellation has been requested.CancellationToken
that throws an OperationCanceledException
if cancellation has been requested. This allows you to easily stop the operation and handle the cancellation in a try-catch
block.
Real-Life Use Case
Imagine a user initiating a search query on a website. If the user decides to cancel the search or the network connection is lost, you want to stop the search operation gracefully. A CancellationToken
can be used to signal the cancellation to the search function, preventing unnecessary resource consumption and improving user experience. Another example is downloading a large file. If the user cancels the download, the CancellationToken allows you to stop the process cleanly, preventing corrupted files and freeing up bandwidth.
Best Practices
IsCancellationRequested
frequently: This ensures a timely response to cancellation requests.CancellationTokenSource
when done: This releases resources associated with the source. Use a using
statement or a finally
block.CancellationToken
to methods that support cancellation: Many built-in asynchronous methods in .NET accept a CancellationToken
parameter. Use it!OperationCanceledException
gracefully: Ensure your application handles the exception and performs any necessary cleanup.
Interview Tip
When discussing CancellationToken
in an interview, highlight its role in cooperative cancellation. Emphasize that the token itself doesn't force cancellation; rather, it's a signal that the code must actively listen for. Explain the importance of checking IsCancellationRequested
regularly and handling the OperationCanceledException
. Be prepared to discuss real-world scenarios where cancellation is crucial, such as long-running tasks, network operations, or UI updates.
When to use them
Use If an operation is quick and trivial, the overhead of cancellation token management may not be worth it.CancellationToken
whenever you have long-running operations that could benefit from being cancelled prematurely. Common scenarios include:
Memory footprint
A CancellationToken
itself is a struct, meaning it's a value type and has a relatively small memory footprint. The CancellationTokenSource
, however, is a class (reference type) and consumes more memory, especially if many tokens are derived from it. Remember to dispose of the CancellationTokenSource
when it's no longer needed to release these resources. Avoid creating excessive numbers of CancellationTokenSource
objects unnecessarily.
Alternatives
While CancellationToken
is the standard way to handle cancellation in .NET, there are alternative approaches:CancellationToken
. It also lacks the structured exception handling provided by CancellationToken
.CancellationToken
is generally preferred for its flexibility, integration with asynchronous programming, and structured exception handling.
Pros
CancellationToken
, making it easy to integrate with existing code.OperationCanceledException
provides a standard way to handle cancellation.
Cons
IsCancellationRequested
, although it's generally minimal.
FAQ
-
What happens if I don't check `IsCancellationRequested`?
If you don't checkIsCancellationRequested
, your operation will continue to run even after cancellation has been requested. TheCancellationToken
only signals the request; it doesn't force the operation to stop. This can lead to wasted resources and unexpected behavior. -
Can I reuse a `CancellationToken`?
No, once aCancellationToken
has been cancelled, it cannot be reset or reused. You need to create a newCancellationTokenSource
andCancellationToken
for each operation that requires cancellation. -
Is `CancellationToken` thread-safe?
Yes,CancellationToken
andCancellationTokenSource
are thread-safe. You can safely access and modify them from multiple threads.