Cancel multiple Tasks at once in .NET C#
February 25, 2014 Leave a comment
You cannot directly interrupt a Task in .NET while it’s running. You can do it indirectly through the CancellationTokenSource object. This object has a CancellationToken property which must be passed into the constructor of the Task:
CancellationTokenSource cancellationTokenSource = new CancellationTokenSource(); CancellationToken cancellationToken = cancellationTokenSource.Token;
You can re-use the same token in the constructor or several tasks:
Task firstTask = Task.Factory.StartNew(() => { for (int i = 0; i < 100000; i++) { cancellationToken.ThrowIfCancellationRequested(); Console.WriteLine(i); } }, cancellationToken); Task secondTask = Task.Factory.StartNew(() => { for (int i = 0; i < int.MaxValue; i++) { cancellationToken.ThrowIfCancellationRequested(); Console.WriteLine(i); } }, cancellationToken);
We simply count up to 100000 in the Task bodies. We’re using the ThrowIfCancellationRequested() method of the cancellation token, I’ll explain shortly what it does.
You can cancel both tasks by calling the Cancel() method of the token like this:
cancellationTokenSource.Cancel();
Note that this method only signals the wish to cancel a task. .NET will not actively interrupt the task, you’ll have to monitor the status through the IsCancellationRequested property. It is your responsibility to stop the task. In this example we’ve used the built-in “convenience” method ThrowIfCancellationRequested() which throws an OperationCanceledException which is a must in order to correctly acknowledge the cancellation. If you forget this step then the task status will not be set correctly. Once the task has been requested the stop it cannot be restarted.
If you need to do something more substantial after cancellation, such as a resource cleanup, then you can monitor cancellation through the IsCancellationRequested and throw the OperationCanceledException yourself:
for (int i = 0; i < 100000; i++) { if (token.IsCancellationRequested) { Console.WriteLine("Task cancellation requested"); throw new OperationCanceledException(token); } else { Console.WriteLine(i); } }
View the list of posts on the Task Parallel Library here.