5using System.Threading.Tasks;
11 private readonly
int max;
12 private readonly Func<int, Exception, TimeSpan> delay;
13 private readonly Action<int, Exception, TimeSpan>? onRetry;
14 private readonly Func<Exception, bool>? shouldRetry;
16 public RetryPolicy(
int maxAttempts, Func<int, Exception, TimeSpan> delayProvider, Action<int, Exception, TimeSpan>? cb, Func<Exception, bool>? shouldRetry =
null)
18 this.max = Math.Max(1, maxAttempts);
19 this.delay = delayProvider;
21 this.shouldRetry = shouldRetry;
24 public async Task ExecuteAsync(Func<CancellationToken, Task> action, CancellationToken ct)
26 for (
int Attempt = 1; ; Attempt++)
28 try { await action(ct);
return; }
29 catch (OperationCanceledException) when (ct.IsCancellationRequested) {
throw; }
30 catch (Exception Ex) when (Attempt < this.max && (this.shouldRetry?.Invoke(Ex) ??
true))
32 TimeSpan Wait = this.delay(Attempt, Ex);
33 this.onRetry?.Invoke(Attempt, Ex, Wait);
34 await Task.Delay(Wait, ct);
39 public async Task<T>
ExecuteAsync<T>(Func<CancellationToken, Task<T>> action, CancellationToken ct)
41 for (
int Attempt = 1; ; Attempt++)
43 try {
return await action(ct).ConfigureAwait(
false); }
44 catch (OperationCanceledException) when (ct.IsCancellationRequested) {
throw; }
45 catch (Exception Ex) when (Attempt < this.max && (this.shouldRetry?.Invoke(Ex) ??
true))
47 TimeSpan Wait = this.delay(Attempt, Ex);
48 this.onRetry?.Invoke(Attempt, Ex, Wait);
49 await Task.Delay(Wait, ct).ConfigureAwait(
false);
async Task< T > ExecuteAsync< T >(Func< CancellationToken, Task< T > > action, CancellationToken ct)
Executes an async action producing a value through the policy pipeline.