// Navigation

CancellationToken for Efficient Asynchronous Programming

p.leadAsynchronous programming can be challenging, especially when it comes to managing long-running operations or dealing with unpredictable user interactions. It is crucial to handle cancellations gracefully to ensure that the application remains responsive and doesn't waste resources on abandoned work. One of the techniques for efficiently and safely managing these scenarios is the use of the CancellationToken class. By accepting a CancellationToken as a parameter, a method can be notified when the caller is no longer interested in the result and can gracefully cancel its work.

What is a CancellationToken?

A CancellationToken is an object that allows you to communicate the cancellation status to an asynchronous operation. It's a way of telling an operation to stop executing if it's no longer needed. For example, if a user cancels a search operation in a web application, you can use a CancellationToken instance to signal to the server to stop processing the request.

One way to use a CancellationToken is with the Task class in C#. The Task class represents an asynchronous operation that can be canceled using a CancellationToken . To use it, you simply pass a CancellationToken to the Task.Run method, which runs the operation asynchronously.

The following code snippet shows how to use a CancellationToken with the Task class:

public async Task DownloadFileAsync(string url,
  string filename,
  HttpClient client,
  CancellationToken cancellationToken)
{
  await client.DownloadFileTaskAsync(url, filename, cancellationToken);
}

In this example, the DownloadFileAsync method takes a URL and a filename as input, along with a CancellationToken . It accepts an instance of the HttpClient class, which is used to download the file. The DownloadFileTaskAsync method is called on the client object, passing in the URL, filename, and cancellationToken. If the CancellationToken is canceled before the download is complete, the Task will be canceled.

By using a CancellationToken , you can make your code more responsive to the requestor. Most asynchronous libraries allow for the passing of the CancellationToken in their methods.

Checking For Cancellation

When you're writing asynchronous code, it's important to handle cancellation gracefully. This is especially true when you're dealing with long-running operations or unpredictable user interactions. One way to handle cancellation is by using a CancellationToken. A CancellationToken is an object that allows the requesting code to signal a cancellation of an asynchronous operation.

Key Considerations
  • Identify the points in your code where cancellation is allowed
  • Determine how you want to handle cancellation at each point
  • Consider the granularity of cancellation
  • Place cancellation checks close to critical points

You can call the ThrowIfCancellationRequested() method to check if the CancellationToken has been canceled and throw an exception if it has. Determining where in your business logic to place the call to ThrowIfCancellationRequested() can be a crucial decision to ensure efficient and safe asynchronous programming.

Cancellation Example
public async Task DownloadFileAsync(List<string> urls,
  string filename,
  HttpClient client,
  CancellationToken cancellationToken)
  {
    try {
      foreach (var url in urls)
      {
        // Check for cancellation before each download
        cancellationToken.ThrowIfCancellationRequested();
        await client.DownloadFileTaskAsync(url, filename, cancellationToken);
      }
    }
    catch (TaskCanceledException ex)
    {
      // Handle cancellation thrown by client.DownloadFileTaskAsync() here
    }
    catch (OperationCanceledException ex)
    {
      // Handle cancellation thrown by ThrowIfCancellationRequested() here
    }
  }

Best Practices

Do This
  • Propagate CancellationToken to all methods
  • Check cancellation at appropriate intervals
  • Handle cancellation exceptions properly
  • Use IsCancellationRequested for non-throwing checks
Consider This
  • Don't cancel after point of no return
  • Balance granularity vs performance
  • Ensure proper resource cleanup
  • Leave objects in valid state

Overall, careful consideration of where to place the call to ThrowIfCancellationRequested() in your business logic is critical to ensure efficient and safe asynchronous programming. Keep in mind that calling the ThrowIfCancellationRequested() method only checks if the cancellation has been requested and throws an exception of type OperationCanceledException if necessary.

Important Notes

If you need to check the state of the cancellation token without throwing an exception, you can use the IsCancellationRequested property. This property returns a boolean value indicating whether cancellation has been requested for the token.

It is important to consider the consequences of cancellation, especially in long-running or expensive operations. You should ensure that any resources acquired during the operation are properly released and any partial results are correctly handled in the event of a cancellation.

Sample Code

For more complete coding examples of asynchronous techniques in .NET, check out the WebSpark repository on GitHub . This repository, developed by Mark Hazleton, provides a wide range of examples of how to use CancellationToken and other asynchronous programming techniques in a safe and efficient manner.

Conclusion

By following best practices for handling cancellations in asynchronous programming, you can ensure that your application remains responsive, efficient, and free from errors caused by abandoned work.

  • Use CancellationToken to gracefully handle cancellations
  • Pass it to all methods involved in the operation
  • Handle exceptions thrown when an operation or task is canceled

With these practices in place, you can write reliable and efficient asynchronous code.

Related Articles

Decorator Pattern with HttpClient

Brief description of how CancellationToken is used with HttpClient and the Decorator Design Pattern.

Cancellation Tokens in ASP.NET APIs

Overview of implementing CancellationToken in ASP.NET APIs by Erik Dahl.

Cancellation Tokens in MVC Core Controllers

Insights into the use of CancellationToken in MVC Core Controllers.

Cancellation in Managed Threads

Microsoft's official documentation on cancellation patterns.