Cancelling a Task is throwing an exception

I am trying to avoid any exceptions when cancelling.

You shouldn’t do that.

Throwing OperationCanceledException is the idiomatic way that “the method you called was cancelled” is expressed in TPL. Don’t fight against that – just expect it.

It’s a good thing, because it means that when you’ve got multiple operations using the same cancellation token, you don’t need to pepper your code at every level with checks to see whether or not the method you’ve just called has actually completed normally or whether it’s returned due to cancellation. You could use CancellationToken.IsCancellationRequested everywhere, but it’ll make your code a lot less elegant in the long run.

Note that there are two pieces of code in your example which are throwing an exception – one within the task itself:

cancelToken.ThrowIfCancellationRequested()

and one where you wait for the task to complete:

task.Wait(cancellationToken.Token);

I don’t think you really want to be passing the cancellation token into the task.Wait call, to be honest… that allows other code to cancel your waiting. Given that you know you’ve just cancelled that token, it’s pointless – it’s bound to throw an exception, whether the task has actually noticed the cancellation yet or not. Options:

  • Use a different cancellation token (so that other code can cancel your wait independently)
  • Use a time-out
  • Just wait for as long as it takes

Leave a Comment