The WaitAndRetryAsync
has several overloads. In your case you have used one which accepts an IEnumerable<TimeSpan>
which defines the retry count and the delays between each attempt.
There are overloads which allows you to define the sleepDurations
dynamically. In those cases you have to provide a sleepDurationProvider
.
In the bellow example I've used this overload:
public static AsyncRetryPolicy<TResult> WaitAndRetryAsync<TResult>(
this PolicyBuilder<TResult> policyBuilder,
int retryCount,
Func<int, DelegateResult<TResult>, Context, TimeSpan> sleepDurationProvider,
Func<DelegateResult<TResult>, TimeSpan, int, Context, Task> onRetryAsync)
int retryCount
: At most how many retry attempts should be issued
Func<int, DelegateResult<TResult>, Context, TimeSpan> sleepDurationProvider
: A user-defined function which receives the number of retry attempt, the result of the attempt, a context and anticipates a TimeSpan
in return
Func<DelegateResult<TResult>, TimeSpan, int, Context, Task> onRetryAsync
: A user-defined function which is called if the policy should be triggered but before the sleep
With this you can achieve the desired behaviour:
.WaitAndRetryAsync(retryCount: 3,
sleepDurationProvider: (int retryCount, DelegateResult<RestResponse> response, Context ctx) =>
{
if (response.Result.StatusCode == HttpStatusCode.InternalServerError)
return TimeSpan.FromMinutes(3);
return retryCount switch
{
1 => TimeSpan.FromSeconds(2),
2 => TimeSpan.FromSeconds(5),
3 => TimeSpan.FromSeconds(15),
_ => TimeSpan.FromSeconds(1) //It won't be used due to the retryCount
};
}, onRetryAsync: (_, __, ___, ____) => Task.CompletedTask);
- If the response's status code is 500 then return with a 3 minutes sleep duration
- For every other cases decide the sleep duration based on the number of attempt
- The
onRetryAsync
delegate needs to be defined otherwise the compiler will not find this overload