To Pass or Not To Pass a Cancellation Token

To Pass or Not To Pass a Cancellation Token

Introduction

In C#, when working with asynchronous operations that support cancellation, it’s a good practice to pass a CancellationToken when appropriate. However, whether you should always pass a CancellationToken depends on the context and requirements of your application. Here are some considerations to help you decide when to pass a CancellationToken:

When to Pass a CancellationToken:

  1. Cancellation Support: If the asynchronous operation you are working with supports cancellation, and you want to give the caller the ability to cancel the operation, you should pass a CancellationToken. For example, operations involving network requests, file I/O, or long-running computations can often benefit from cancellation support.
  2. Long-Running Operations: When you have long-running asynchronous operations that could potentially block the application, it’s essential to pass a CancellationToken. This allows users or the application itself to cancel the operation if it takes too long.
  3. User-Initiated Actions: In user interfaces (UI), when you trigger asynchronous operations based on user actions (e.g., clicking a cancel button), it’s crucial to use a CancellationToken to enable users to cancel those operations.
  4. Cascading Cancellation: If your application orchestrates multiple asynchronous operations, you can create a linked set of CancellationTokens using CancellationTokenSource and propagate cancellation through linked tokens. This allows for graceful cancellation of entire workflows.

When Not to Pass a CancellationToken:

  1. Non-Cancellable Operations: If the asynchronous operation cannot be reasonably canceled or if cancellation is not needed for the specific scenario, there’s no need to pass a CancellationToken. For example, lightweight, non-blocking operations like reading a configuration file may not require cancellation support.
  2. Simple Operations: For very simple asynchronous operations that complete quickly and don’t involve external resources or waiting, you may choose not to use a CancellationToken.
  3. Performance Considerations: Passing a CancellationToken involves some overhead, especially when creating linked tokens or dealing with complex cancellation scenarios. In performance-critical scenarios, consider whether the overhead of passing a token is justified.
  4. Explicit Cancellation Not Required: In some cases, you may be using asynchronous code to improve responsiveness but don’t necessarily need to cancel the operation explicitly. For example, you may want to load data asynchronously to prevent blocking the UI thread, but you don’t expect users to cancel the operation.

Conclusion

The decision to pass a CancellationToken should be based on whether cancellation support is needed for a particular asynchronous operation.

Always consider the context, user requirements, and the potential impact on application responsiveness when deciding whether to use a CancellationToken.

When cancellation is relevant and provides a valuable feature, it’s a good practice to support it by passing a CancellationToken.

The official documentation for cancellation tokens can be found here: – https://learn.microsoft.com/en-us/dotnet/api/system.threading.cancellationtoken?view=net-8.0

I have written other related posts here: – Choose await/async over Task Alone, Asynchronous Testing with NUnit and C#

Stephen

Hi, my name is Stephen Finchett. I have been a software engineer for over 30 years and worked on complex, business critical, multi-user systems for all of my career. For the last 15 years, I have been concentrating on web based solutions using the Microsoft Stack including ASP.Net, C#, TypeScript, SQL Server and running everything at scale within Kubernetes.