Cancellation Token Concept: A Practical Guide
Cancellation Token in .NET: A Practical Guide
Cancellation tokens are a powerful feature in .NET that allow you to manage and gracefully cancel long-running tasks. Whether you're dealing with API requests, database operations, or any asynchronous processing, cancellation tokens help you maintain responsiveness and optimize resource usage. In this blog, we'll explore how cancellation tokens work and provide a practical example of their usage in a .NET API.
Table of Contents
Understanding Cancellation Tokens
How Cancellation Tokens Work with Frontend/Browser
Implementing Cancellation Tokens in .NET
A Real-World Example
Conclusion
1. Understanding Cancellation Tokens
Cancellation tokens in .NET are primarily used to signal and manage the cancellation of tasks. They are particularly useful in scenarios where a task might no longer be needed or where it's essential to free up resources if a client disconnects or a timeout occurs.
Key components:
CancellationTokenSource
: This creates a cancellation token and manages the cancellation.CancellationToken
: This is the token itself, which is passed to tasks that might need to be canceled.OperationCanceledException
: This exception is thrown when a task is canceled using a cancellation token.
2. How Cancellation Tokens Work with Frontend/Browser
Although cancellation tokens are a server-side feature, they work closely with the frontend in specific scenarios:
Client Disconnection: If a user closes a browser tab or navigates away, the server can detect this and cancel ongoing tasks using the
HttpContext.RequestAborted
cancellation token.Timeouts: When a frontend sets a timeout for an HTTP request, the server detects this cancellation through the same token mechanism.
User-Initiated Cancellation: In advanced scenarios, the frontend might provide the option to cancel an operation, which the backend can handle using a cancellation token.
3. Implementing Cancellation Tokens in .NET
To implement cancellation tokens in your .NET API, follow these steps:
Create and Pass the Cancellation Token
Ensure that every async method accepts a
CancellationToken
parameter to allow for potential cancellation.public async Task<IActionResult> GetDataAsync(CancellationToken cancellationToken) { var data = await _dataService.GetDataAsync(cancellationToken); return Ok(data); }
Handle Cancellation Gracefully
Within your tasks, periodically check the cancellation token to exit early if a cancellation has been requested.
public async Task<List<MyData>> GetDataAsync(CancellationToken cancellationToken) { await Task.Delay(5000, cancellationToken); cancellationToken.ThrowIfCancellationRequested(); return await _context.MyData.ToListAsync(cancellationToken); }
Pass Cancellation Token in HTTP Client Calls
When making HTTP requests using
HttpClient
, pass the cancellation token to handle request cancellations properly.public async Task<HttpResponseMessage> GetExternalDataAsync(CancellationToken cancellationToken) { var request = new HttpRequestMessage(HttpMethod.Get, "https://api.example.com/data"); return await _httpClient.SendAsync(request, cancellationToken); }
4. A Real-World Example
Let’s dive into a practical example where a cancellation token is used in a .NET API to handle a request that fetches data from a database.
[ApiController]
[Route("api/[controller]")]
public class DataController : ControllerBase
{
private readonly IDataService _dataService;
public DataController(IDataService dataService)
{
_dataService = dataService;
}
[HttpGet("data")]
public async Task<IActionResult> GetData(CancellationToken cancellationToken)
{
try
{
// Fetch data with cancellation support
var data = await _dataService.GetDataAsync(cancellationToken);
return Ok(data);
}
catch (OperationCanceledException)
{
// Handle the cancellation request
return StatusCode(StatusCodes.Status499ClientClosedRequest, "Request was canceled.");
}
}
}
public class DataService : IDataService
{
private readonly ApplicationDbContext _context;
public DataService(ApplicationDbContext context)
{
_context = context;
}
public async Task<List<MyData>> GetDataAsync(CancellationToken cancellationToken)
{
// Simulate a delay and then fetch data from the database
await Task.Delay(3000, cancellationToken);
return await _context.MyData.ToListAsync(cancellationToken);
}
}
5. Conclusion
Cancellation tokens are an essential feature in .NET for handling the cancellation of tasks gracefully, especially in API-driven applications. By understanding and implementing them properly, you can make your applications more responsive, resource-efficient, and capable of handling real-world scenarios like client disconnections and timeouts.
In this blog, we've covered the basics of cancellation tokens, how they interact with frontend requests, and a practical example of their use in a .NET API. Implementing cancellation tokens can significantly improve the performance and reliability of your applications, ensuring that resources are used efficiently and that your services can handle interruptions gracefully.
With this guide, you should now have a good understanding of how to use cancellation tokens in your .NET applications. Whether you're developing APIs or working with long-running tasks, cancellation tokens are a valuable tool to keep in your toolkit.
Subscribe to my newsletter
Read articles from Ejan Shrestha directly inside your inbox. Subscribe to the newsletter, and don't miss out.
Written by