Letβs go through Cancellation Tokens in C# β a standard way to cancel running tasks or asynchronous operations safely.
π 1. What is a Cancellation Token?
-
CancellationToken allows cooperative cancellation of tasks or async operations.
-
Instead of forcefully killing a thread, the task checks periodically if it should cancel.
-
Works with:
-
Task
/Task<T>
-
async
/await
-
Parallel
operations
-
π 2. Creating a CancellationToken
using System;
using System.Threading;
using System.Threading.Tasks;
CancellationTokenSource cts = new CancellationTokenSource();
CancellationToken token = cts.Token;
-
CancellationTokenSource
β controls the token -
CancellationToken
β passed to tasks to observe cancellation
π 3. Using CancellationToken in a Task
Task.Run(() =>
{
for (int i = 0; i < 10; i++)
{
token.ThrowIfCancellationRequested(); // Check for cancellation
Console.WriteLine($"Processing {i}");
Thread.Sleep(500);
}
}, token);
-
ThrowIfCancellationRequested()
throws OperationCanceledException if cancelled -
Task can then stop gracefully
π 4. Cancelling a Task
cts.Cancel(); // Request cancellation
-
Task observes cancellation via
token
and stops execution -
Wrap in try-catch to handle cancellation:
try
{
await Task.Run(() =>
{
for (int i = 0; i < 10; i++)
{
token.ThrowIfCancellationRequested();
Thread.Sleep(500);
}
}, token);
}
catch (OperationCanceledException)
{
Console.WriteLine("Task was canceled!");
}
π 5. Using CancellationToken with Async Methods
async Task DownloadFileAsync(string url, CancellationToken token)
{
for (int i = 0; i < 10; i++)
{
token.ThrowIfCancellationRequested();
await Task.Delay(500); // Simulate download
Console.WriteLine($"Downloaded {i * 10}%");
}
}
- Pass
token
to async methods for cooperative cancellation
π 6. Parallel Loops with CancellationToken
ParallelOptions options = new ParallelOptions
{
CancellationToken = token
};
try
{
Parallel.For(0, 10, options, i =>
{
Console.WriteLine(i);
Thread.Sleep(200);
});
}
catch (OperationCanceledException)
{
Console.WriteLine("Parallel loop canceled!");
}
- Supports cooperative cancellation in parallel loops
π 7. Full Example
using System;
using System.Threading;
using System.Threading.Tasks;
class Program
{
static async Task Main(string[] args)
{
// Create a cancellation token source
CancellationTokenSource cts = new CancellationTokenSource();
// Register a task to cancel after 3 seconds
cts.CancelAfter(3000);
try
{
Console.WriteLine("Starting long-running task...");
int result = await LongRunningOperationAsync(cts.Token);
Console.WriteLine($"Task completed successfully: {result}");
}
catch (OperationCanceledException)
{
Console.WriteLine("Task was canceled!");
}
finally
{
cts.Dispose();
}
}
// Async method that supports cancellation
static async Task<int> LongRunningOperationAsync(CancellationToken token)
{
int sum = 0;
for (int i = 1; i <= 10; i++)
{
token.ThrowIfCancellationRequested(); // check for cancellation
Console.WriteLine($"Processing {i}...");
sum += i;
await Task.Delay(1000); // simulate work
}
return sum;
}
}
π 8. How It Works
-
Create a
CancellationTokenSource
β produces aCancellationToken
. -
Pass the token to a method that supports cancellation.
-
Inside the method:
-
Periodically check
token.IsCancellationRequested
or -
Call
token.ThrowIfCancellationRequested()
to stop and throw anOperationCanceledException
.
-
-
Cancel the task by calling
cts.Cancel()
orcts.CancelAfter(milliseconds)
. -
Handle the cancellation with a
try-catch
block.
π 9. Output Example (if canceled after 3 seconds)
Starting long-running task...
Processing 1...
Processing 2...
Processing 3...
Task was canceled!
- Notice it stops mid-loop when cancellation is requested.
β Summary:
-
CancellationToken
= signal to stop work. -
CancellationTokenSource
= triggers that signal. -
ThrowIfCancellationRequested()
= the typical way to stop a task cleanly.
π 11. Best Practices
-
Always pass the token to methods performing cancellable work.
-
Use ThrowIfCancellationRequested() for clean exit.
-
Wrap task execution in try-catch to handle
OperationCanceledException
. -
Use Dispose() on
CancellationTokenSource
when done.
π 12. Summary Table
Feature | Description |
---|---|
CancellationTokenSource | Creates and controls cancellation |
CancellationToken | Observed by tasks to respond to cancellation |
Cancel a task | cts.Cancel() |
Check for cancellation | token.ThrowIfCancellationRequested() |
Async & Parallel support | Works with async/await and Parallel loops |
Best practice | Cooperative, graceful cancellation |
β Tip:
-
Use CancellationToken whenever your task might take a long time or may need to be cancelled by the user.
-
Avoid killing threads; instead, let tasks cooperate for graceful exit.