Skip to content
~/writing
.NET

Cancellation tokens: a practical guide

/ 2 min read / Ejan Shrestha

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

  1. Understanding Cancellation Tokens

  2. How Cancellation Tokens Work with Frontend/Browser

  3. Implementing Cancellation Tokens in .NET

  4. A Real-World Example

  5. 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:

  1. 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);
     }
  2. 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);
     }
  3. 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.

Ejan Shresthaइजन श्रेष्ठ

Senior Software Engineer, backend and .NET modernisation

Senior software engineer in Kathmandu with 4+ years shipping .NET for insurance and enterprise. I own reliability and modernisation for an insurance platform of 50 .NET projects on Kubernetes: structured logging and tracing across old and new services, the plan off end-of-life .NET to .NET 10, and the fix for socket exhaustion across ~390 call sites.

Selected impact

  • ~390Ending socket exhaustion across the platform. The error class disappeared from production logs, and outbound HTTP now has one place for retries and tracing.
  • 1 IDOne trace from gateway to database. One correlation ID now follows a request end to end.
  • 61%From end-of-life .NET to .NET 10. A sequenced roadmap with known risks; the first services already run on .NET 10.
  • v16A public website on Next.js 16. Shipped to production with a tested rollback path.
  • 4A release standard people follow. Releases are predictable enough to schedule.

Experience

  1. Senior Software Engineer, Himalayan Everest Insurance

    Jan 2025 – present

    Kathmandu, hybrid

    • Own backend reliability and modernisation for an insurance platform of 50 .NET projects, deployed as 28 Kubernetes workloads, across accounting, claims, reinsurance and reporting.
    • Leading the upgrade from .NET Core 2.2, 3.1 and 5 to .NET 10, including the IdentityServer4 replacement.
    • Built structured logging and tracing across every service.
    • Upgraded the public website and CMS to Next.js 16, React 19, Strapi 5 and Node 24.
  2. .NET Developer, EKbana Solutions

    Jul 2022 – Nov 2024

    Lalitpur, on-site

    • Designed backend services for enterprise insurance workflows with ASP.NET Core, PostgreSQL, EF Core and Dapper.
    • Built REST APIs and integrations for customer portals, payments and external partners.
    • Ran background workflows on Hangfire with idempotency, retries and failure recovery.
    • Shipped on Docker, Linux, Nginx/Traefik and Kubernetes; worked on IdentityServer, JWT and RBAC.
  3. Dotnet Developer, NBIT

    Jan 2022 – Jun 2022

    Lalitpur

    • Built and maintained .NET Framework applications for client projects.
  4. Data Specialist, CloudFactory

    Nov 2017 – Jun 2022

    Kathmandu

    • Delivered high-accuracy data work for international clients while completing my degree.