1
Vote

Incorrect behavior in RetryPolicy.ExecuteAsync when TaskCanceledException is thrown

description

Consider the following code:
await myRetryPolicy.ExecuteAsync(async () =>
{
    await Task.Delay(100).ContinueWith(t => { throw new TaskCanceledException(); });
});
We would expect the operation to be retried as many times as specified in myRetryPolicy. However, in reality no retries will take place and the TaskCanceledException will be propagated to the outer await.

I believe the issue is in AsyncExecution<T>.ExecuteAsyncContinueWith(Task<TResult> runningTask):
if (!runningTask.IsFaulted || this.cancellationToken.IsCancellationRequested)
{
      return runningTask;
}
Since a canceled task is not considered faulted, it is returned as if successful or canceled via the cancellation token, where in fact neither is correct (the overload with the cancellation token wasn't even called by the user).

comments