Why You Should Learn About Cancellation Token in .NET (C# version)
Introduced in .NET 4, cancellation token can help stop processing abandoned requests and thus making your application more responsive.
What are cancellation token
Let’s say we have a long running process that user can initiate. Now, later at some point of time, while it is still executing, user may not feel the need of the result. May be the user loose the interest or he/she may have initiated the process accidentally or could be any reason. Though, user can simply discard the application, the server may be still running the process unaware that the user’s absence. This is where cancellation token comes into play.
Cancellation token are useful when we want to detect some events and based on that we would like to stop the long running process. This is extremely useful to save expensive server resources and making your application more responsive.
The overall approach is to:
- Create an instance of cancellation token source, which is responsible for generating and managing the token.
- Using the instance, we can generate the token and pass it as an argument to the long running method.
- In the long running process, detect if the cancellation is requested. If so, perform the cancellation of task.
Now, let’s see this by example.
How to use cancellation token
Let’s say we have following code:
public async Task PerformOperationAsync()
{
Console.WriteLine("Operation started.");
await Task.Delay(5000); // Simulates a long-running task
Console.WriteLine("Operation completed.");
}
// Usage
await PerformOperationAsync();
As you can see from above example, if user calls PerformOperationAsync function, and leaves the application after waiting for 2 seconds, the server will still run the function, until 5 seconds are completed. Now, this an example, in real life, it could be running a query against database or calling an external API.
The same code can be written using cancellation token as below:
var cancellationTokenSource = new CancellationTokenSource();
var task = PerformOperationAsync(cancellationTokenSource.Token);
// Simulation of user abandoing the process
Task.Delay(2000).ContinueWith(_ => cancellationTokenSource.Cancel());
await task;
public async Task PerformOperationAsync(CancellationToken cancellationToken)
{
Console.WriteLine("Operation started.");
try
{
await Task.Delay(5000, cancellationToken);
Console.WriteLine("Operation completed.");
}
catch (OperationCanceledException)
{
Console.WriteLine("Operation canceled.");
}
}
Let’s break the changes:
- We first updated code by creating token source:
var cancellationTokenSource = new CancellationTokenSource();
2. We pass the token generated to the function (long running task) as an argument:
var task = PerformOperationAsync(cancellationTokenSource.Token);
3. After 2 seconds, we are calling cancel method of token source to communicate the long running process that hey! user has abandoned you, so stop running now.
Task.Delay(2000).ContinueWith(_ => cancellationTokenSource.Cancel());
Use case scenario in API
Let’s see one more example of this in ASP.NET CORE Web API.
using Microsoft.AspNetCore.Mvc;
using System.Threading;
using System.Threading.Tasks;
[ApiController]
[Route("[controller]")]
public class SampleController : ControllerBase
{
[HttpGet("getData")]
public async Task<IActionResult> GetData(CancellationToken cancellationToken)
{
if (cancellationToken.IsCancellationRequested){
return Results.StatusCode(500);
}
return Ok("Operation completed successfully.");
}
}
Now, you may be wondering that how user will pass the cancellationToken object? right? the point is ASP.NET core will auto inject the token object based on two cases.
- Client Disconnects: If the client closes the browser or cancels the request, the server will notice and cancel the associated CancellationToken.
- Token Propagation: The token is passed to the operations, which can check for cancellation using cancellationToken.IsCancellationRequested() method.
Conclusion
If you have an API project, console application, or any situation where the application might hang, it’s beneficial to use the capabilities of a CancellationToken. This makes your application more responsive to users abandoning a session. Implementing it is straightforward, and it can save significant computing resources if a user closes the connection.