C# > Asynchronous Programming > Parallel Programming > CancellationToken
Asynchronous Task with CancellationToken
This snippet demonstrates how to perform an asynchronous task and gracefully handle cancellation requests using CancellationToken
in C#. It creates a simple task that simulates work, checks for cancellation requests during its execution, and stops processing if cancellation is requested.
Code Snippet
This code defines an asynchronous method `LongRunningTask` that simulates a long-running operation. It takes a `CancellationToken` as input. Inside the loop, it checks `cancellationToken.IsCancellationRequested` to see if a cancellation has been requested. If so, it stops the task execution. The `Main` method creates a `CancellationTokenSource`, retrieves its token, starts the task, waits briefly, cancels the task using `cts.Cancel()`, and then awaits the task's completion. A `try-catch` block handles the `TaskCanceledException` that is thrown when a task is cancelled.
using System;
using System.Threading;
using System.Threading.Tasks;
public class CancellationExample
{
public static async Task LongRunningTask(CancellationToken cancellationToken)
{
Console.WriteLine("Starting long-running task...");
for (int i = 0; i < 100; i++)
{
// Check for cancellation request
if (cancellationToken.IsCancellationRequested)
{
Console.WriteLine("Task cancellation requested. Exiting...");
return; // Stop execution
}
// Simulate some work
Console.WriteLine($"Task running... {i}%");
await Task.Delay(50, cancellationToken); // Asynchronously wait for 50ms
}
Console.WriteLine("Long-running task completed.");
}
public static async Task Main(string[] args)
{
// Create a CancellationTokenSource
CancellationTokenSource cts = new CancellationTokenSource();
// Get the CancellationToken
CancellationToken token = cts.Token;
// Start the long-running task
Task task = LongRunningTask(token);
// Allow the task to run for a bit, then cancel it
await Task.Delay(200);
Console.WriteLine("Requesting cancellation...");
cts.Cancel();
// Wait for the task to complete (or be cancelled)
try
{
await task;
}
catch (TaskCanceledException)
{
Console.WriteLine("Task was cancelled.");
}
catch (Exception ex)
{
Console.WriteLine($"Exception: {ex.Message}");
}
Console.WriteLine("Program finished.");
}
}
Concepts Behind the Snippet
This snippet uses the following concepts:
Real-Life Use Case
Consider a file download operation in a web application. The download task can be cancelled if the user closes the browser or navigates away from the page. A `CancellationToken` allows the server to stop the download and free up resources.
Best Practices
cancellationToken.IsCancellationRequested
frequently in long-running operations.CancellationToken
to asynchronous methods that support cancellation.TaskCanceledException
properly to ensure resources are released.cancellationToken.ThrowIfCancellationRequested()
to throw an exception immediately when cancellation is requested.
When to Use Them
Use CancellationToken
when you have a long-running operation and need to provide the user (or another part of the system) with the ability to stop it prematurely. This is particularly useful in GUI applications, web servers, and services where responsiveness is crucial.
Memory Footprint
The memory footprint of using `CancellationToken` is relatively small. A `CancellationTokenSource` and its associated `CancellationToken` consume a few bytes of memory. The overhead is minimal compared to the resources consumed by the long-running operation itself.
Alternatives
Alternatives to using `CancellationToken` for stopping asynchronous operations include: `CancellationToken` provides a cleaner and more robust solution for managing cancellation requests.
Pros
Cons
IsCancellationRequested
property.TaskCanceledException
.
FAQ
-
What happens if I don't check for cancellation?
If you don't check for cancellation, the long-running operation will continue to execute even if cancellation is requested. This can lead to wasted resources and potentially incorrect results. -
Can I reuse a CancellationToken?
Yes, you can pass the same `CancellationToken` to multiple tasks. When the token is cancelled, all tasks using it will be notified. -
What's the difference between Cancel() and CancelAfter()?
`Cancel()` immediately requests cancellation. `CancelAfter(delay)` requests cancellation after a specified delay.