Under what circumstances is a deferred task expected to throw TaskCanceledException?

I am taking advantage of the asynchronous pattern execution capability while handling cancellation of asynchronous operations:

public async Task InvokeAsync(CancellationToken cancellationToken)
{
    using(cancellationToken.Register(handler.Stop))
    {
        try
        {
            await handler.HandleAsync();
        }
        catch(HandlerStoppedException ex)
        {
            cancellationToken.ThrowIfCancellationRequested();
            throw;
        }
    }
}

      

The method calls an asynchronous component that provides some kind of cancellation mechanism. The cancellation token sets up a callback to invoke the cancellation mechanism when the token signals cancellation request is requested.

I can call this method in my tests to implement its function during the timeout.

async Task TestInvoke()
{
    using (var timeout = new CancellationTokenSource(TimeSpan.FromSeconds(10))
    {
        try
        {
            await InvokeAsync(timeout.Token);
        }
        catch (TaskCancelledException ex)
        {
            if (ex.CancellationToken == timeout.Token)
            {
                throw new TimeoutException(
                    "Operation failed to complete in the allowed time.", ex);
            }

            throw;
        }
    }
}

      

My expectation is that throwing OperationCanceledException

inside a method async

will cause the method returned by the Task

method to return to the Canceled state. Then I expect any attempts to wait for this canceled task to return TaskCanceledException

.

In my current scenario (the code is very similar to the one above) I get instead OperationCanceledException

when I wait for this task. If I look at the status of the task, I see that it is in the Canceled state and has no exception associated with it.

More curious, if I call Wait()

in the task, it will select the AggregateException

one containing the expected instead TaskCanceledException

.

Under what circumstances will an expected canceled task kick out OperationCanceledException

instead of the more typical one TaskCanceledException

?

+3


source to share


1 answer


Under what circumstances will an awaited canceled task kick out OperationCanceledException

instead of a more typical one TaskCanceledException

?

This question is too broad. Even if we list all the scenarios where this happens today, this may change tomorrow.

I'll say this instead:



  • TaskCanceledException

    is not more typical. It was originally used in task-based dynamic parallelism, which has nothing to do with asynchronous programming.
  • OperationCanceledException

    is the base class for TaskCanceledException

    . In your code, you should never break TaskCanceledException

    (unless you are doing parallelism dynamic tasks and to access TaskCanceledException.Task

    ).

Just catch it OperationCanceledException

.

+4


source







All Articles