Asynchronous programming is essential for building responsive applications, but it comes with challenges - particularly when you need to cancel operations.
Here's how to safely implement cancellation in C#.
Using CancellationTokenSource
The key to proper cancellation is the CancellationTokenSource class. This provides a token that can be passed to async methods and monitored for cancellation requests.
// Create a cancellation source with timeout
var cts = new CancellationTokenSource(TimeSpan.FromSeconds(10));
var token = cts.Token;
try
{
// Pass token to async operations
await DoLongRunningTaskAsync(token);
}
catch (OperationCanceledException)
{
// Handle cancellation gracefully
Console.WriteLine("Operation was canceled");
}
finally
{
// Always dispose the CancellationTokenSource
cts.Dispose();
}
Implementing Cancellation in Your Methods
When writing cancellable async methods, check for cancellation at appropriate points:
async Task DoLongRunningTaskAsync(CancellationToken token)
{
// Check before starting expensive work
token.ThrowIfCancellationRequested();
for (int i = 0; i < 100; i++)
{
// Periodically check during loops
if (token.IsCancellationRequested)
{
// Clean up resources if needed
CleanupResources();
// Then throw the standard exception
throw new OperationCanceledException(token);
}
await Task.Delay(100, token); // Built-in methods accept tokens
}
}
Best Practices
- Always dispose of
CancellationTokenSource objects
- Use
token.ThrowIfCancellationRequested() for cleaner code
- Check for cancellation before expensive operations
- Pass the token to all nested async calls
- Handle
OperationCanceledException appropriately in your calling code
By following these patterns, you can ensure your async operations respond promptly to cancellation requests while maintaining clean, resource-efficient code.
Walt is a computer scientist, software engineer, startup founder and previous mentor for a coding bootcamp. He has been creating software for the past 20 years.
Last updated on: