CancellationTokens 2.0

Thomas Heijtink
4 min readJul 2, 2023

Background

Cancellation tokens were introduced in 2010 as part of .NET Framework 4.0. As engineers have become more aware of resource costs due to cloud computing and containerization. We’ve become more appreciative of features which can help us reduce those costs and resources in general at a more fine grained level.

Cancellation tokens is one of those features which help us to achieve this. But as with many new features they also pose drawbacks.

Drawbacks

One of the drawbacks of cancellation tokens is the fact that they have to be passed from the ports/driving side of an application or system to the adapter/driven side in order to save on IO or networking costs and reduce the chance of threat starvation. This is especially awkward for layers or modules which have absolutely no interest or awareness regarding the cancellability of an operation which reside in infrastructure related concerns.

Another major drawback is that the cancellation token is often viewed as an optional parameter. This doesn’t only increase noise in situations where cancellation is not applicable or an option. But also interferes with the params keyword. As, as of writing, the documentation states:

No additional parameters are permitted after the params keyword in a method declaration, and only one params keyword is permitted in a method declaration.

Mitigation

So how could we mitigate these drawbacks in order to lessen the blow and impact such Cancellation Tokens may have on our system?

One way to do this is to capture the cancellation token from incoming requests. Be it a web API call, message bus message or SignalR signal 😊. Instead of passing it on to the next method, we store it and make it available for objects which are interested in such a cancellation option.

In this solution I’m going to show you how:

  1. To design a wrapper class to store the cancellation token
  2. To capture the cancellation token in an asp.net core IActionFilter
  3. To inject such wrapper class in an illustrative EmailService
  4. To automatically link the CancellationToken in every EF Core call to the database.

The wrapper class is pretty simple and could look as follows:

CancellationTokenContext

This wrapper class can be bootstrapped as a scoped instance in de Program.cs or Startup.cs.

Bootstrapping the CancellationTokenContext

The CancellationContext is captured using an IActionFilter in the following way:

CaptureCancellationTokenFilter

Now we must configure the filter in such a way that it will capture the cancellation token on all incoming requests like this:

Configuring the CaptureCancellationTokenFilter

The next step will be using the IProvideCancellationToken in a service which might benefit from having a CancellationToken .

Example of using the CancellationToken

This works great for services like this. But if we have to remember to always pass the CancellationToken every time we hit the database, even that would seem a bit repetitive or mundane. So why not create an EF Core interceptor which would do this for us every time we execute a query or command.

EF Core Interceptor

This interceptor can be configured as follows:

Configure the CancellationInterceptor

And that’s it. The examples are slightly simplified for illustrative purposes and might have to be tweaked depending on your context and requirements. But I hope this will start a new trend to not pass the CancellationToken to every method, because it might in the end be needed somewhere downstream.

But the question remains: will we ever get an option to cancel our cancellation? 😂

--

--

Thomas Heijtink

A software developer since 2008. He loves coding and everything that comes with it. From cradle to consumer and from personal development to team building.