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. TheCancellationTokenonly 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 aCancellationTokenhas been cancelled, it cannot be reset or reused. You need to create a newCancellationTokenSourceandCancellationTokenfor each operation that requires cancellation. -
Is `CancellationToken` thread-safe?
Yes,CancellationTokenandCancellationTokenSourceare thread-safe. You can safely access and modify them from multiple threads.