---
title: "Cancel WhenAny - linked CancellationTokenSource"
description: "In today's short post, I will show you how to cancel a Task with multiple inputs (aka multiple `CancellationToken`s) using `CancellationTokenSource` and `CancellationTokenSource.CreateLinkedTokenSource`."
updated: 2024-05-28
tags: ["C#", ".NET"]
canonical: "https://steven-giesel.com/blogPost/cd950c5f-467b-48a3-99fe-e72865460579/cancel-whenany-linked-cancellationtokensource"
---

# Cancel WhenAny - linked CancellationTokenSource

In today's short post, I will show you how to cancel a Task with multiple inputs (aka multiple `CancellationToken`s) using `CancellationTokenSource` and `CancellationTokenSource.CreateLinkedTokenSource`.

## Problem
Imagine you have a long-running task you want to shutdown gracefully (or not) and have to listen to multiple sources of cancellation. That can be common in `BackgroundService` or `IHostedService` implementations where you want to listen to the `IHostApplicationLifetime.ApplicationStopping` event and also to some other event or condition.

```csharp
// Triggered when the application host is starting a graceful shutdown.
var hostToken = IHostApplicationLifetime.ApplicationStopping; 

// Some other source for cancellation passed in by the method
var otherToken = ...;
```

Now you want to create a `CancellationToken` that will be triggered when either of the tokens is cancelled. But a method normally only accepts a single token:
```csharp
await Task.Delay(Timeout.Infinite, token); // You can't pass two tokens here
```

The solution: [`CancellationTokenSource.CreateLinkedTokenSource`](https://learn.microsoft.com/en-us/dotnet/api/system.threading.cancellationtokensource.createlinkedtokensource?view=net-8.0). It creates a new `CancellationTokenSource` that will be canceled when any of the linked tokens is canceled. You can pass in as many tokens as you want and it returns a new `CancellationTokenSource`, which you can use to create a `CancellationToken` for your task.

```csharp
using var linkedTokenSource = CancellationTokenSource.CreateLinkedTokenSource(hostToken, otherToken);
var linkedToken = linkedTokenSource.Token;

await Task.Delay(Timeout.Infinite, linkedToken); // Now you can pass the linked token
```

Be aware that `CancellationTokenSource` is an `IDisposable` and should be disposed of when you are done with it. The `using` statement is a good way to ensure that.

You can also cancel the linked token source manually to indicate that the task should be canceled. The "source" tokens will stay unaffected, only the linked token will be canceled.
```csharp
using var t1 = new CancellationTokenSource();
using var t2 = new CancellationTokenSource();
using var t3 = CancellationTokenSource.CreateLinkedTokenSource(t1.Token, t2.Token);

t3.Cancel();

Console.WriteLine(t1.IsCancellationRequested); // False
Console.WriteLine(t2.IsCancellationRequested); // False
Console.WriteLine(t3.IsCancellationRequested); // True
```
