<PackageReference Include="Polly" Version="8.5.1" />

RetryEngine

static class RetryEngine
using Polly.Utilities; using System; using System.Collections.Generic; using System.Diagnostics; using System.Runtime.CompilerServices; using System.Threading; namespace Polly.Retry { internal static class RetryEngine { [System.Runtime.CompilerServices.NullableContext(1)] [DebuggerDisableUserUnhandledExceptions] internal static TResult Implementation<[System.Runtime.CompilerServices.Nullable(2)] TResult>(Func<Context, CancellationToken, TResult> action, Context context, ExceptionPredicates shouldRetryExceptionPredicates, ResultPredicates<TResult> shouldRetryResultPredicates, Action<DelegateResult<TResult>, TimeSpan, int, Context> onRetry, CancellationToken cancellationToken, int permittedRetryCount = int.MaxValue, [System.Runtime.CompilerServices.Nullable(2)] IEnumerable<TimeSpan> sleepDurationsEnumerable = null, [System.Runtime.CompilerServices.Nullable(new byte[] { 2, 1, 1, 1 })] Func<int, DelegateResult<TResult>, Context, TimeSpan> sleepDurationProvider = null) { int num = 0; using (IEnumerator<TimeSpan> enumerator = sleepDurationsEnumerable?.GetEnumerator()) { while (true) { cancellationToken.ThrowIfCancellationRequested(); DelegateResult<TResult> delegateResult; try { TResult result = action(context, cancellationToken); if (!shouldRetryResultPredicates.AnyMatch(result)) return result; if (num >= permittedRetryCount || !(enumerator?.MoveNext() ?? true)) return result; delegateResult = new DelegateResult<TResult>(result); } catch (Exception ex) { Exception ex2 = shouldRetryExceptionPredicates.FirstMatchOrDefault(ex); if (ex2 == null) throw; if (num >= permittedRetryCount || !(enumerator?.MoveNext() ?? true)) { ex2.RethrowWithOriginalStackTraceIfDiffersFrom(ex); throw; } delegateResult = new DelegateResult<TResult>(ex2); } if (num < 2147483647) num++; TimeSpan timeSpan = (enumerator != null) ? enumerator.Current : (sleepDurationProvider?.Invoke(num, delegateResult, context) ?? TimeSpan.Zero); onRetry(delegateResult, timeSpan, num, context); if (timeSpan > TimeSpan.Zero) SystemClock.Sleep(timeSpan, cancellationToken); } } } } }