RetryEngine
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.ExceptionServices;
using System.Threading;
using System.Threading.Tasks;
namespace Polly.Retry
{
internal static class RetryEngine
{
internal static TResult Implementation<TResult>(Func<TResult> action, IEnumerable<ExceptionPredicate> shouldRetryExceptionPredicates, IEnumerable<ResultPredicate<TResult>> shouldRetryResultPredicates, Func<IRetryPolicyState<TResult>> policyStateFactory)
{
IRetryPolicyState<TResult> retryPolicyState = policyStateFactory();
DelegateResult<TResult> delegateOutcome;
Exception ex;
while (true) {
try {
delegateOutcome = (DelegateResult<TResult>)new DelegateResult<TResult>(action());
if (!shouldRetryResultPredicates.Any((ResultPredicate<TResult> predicate) => predicate(((DelegateResult<TResult>)delegateOutcome).Result)))
return ((DelegateResult<TResult>)delegateOutcome).Result;
if (!retryPolicyState.CanRetry((DelegateResult<TResult>)delegateOutcome))
return ((DelegateResult<TResult>)delegateOutcome).Result;
} catch (Exception ex2) {
Exception ex3 = ex = ex2;
if (!shouldRetryExceptionPredicates.Any((ExceptionPredicate predicate) => predicate(ex)))
throw;
if (!retryPolicyState.CanRetry(new DelegateResult<TResult>(ex)))
throw;
}
}
}
internal static async Task<TResult> ImplementationAsync<TResult>(Func<CancellationToken, Task<TResult>> action, CancellationToken cancellationToken, IEnumerable<ExceptionPredicate> shouldRetryExceptionPredicates, IEnumerable<ResultPredicate<TResult>> shouldRetryResultPredicates, Func<IRetryPolicyState<TResult>> policyStateFactory, bool continueOnCapturedContext)
{
IRetryPolicyState<TResult> policyState = policyStateFactory();
DelegateResult<TResult> delegateOutcome;
Exception ex;
while (true) {
cancellationToken.ThrowIfCancellationRequested();
try {
<>c__DisplayClass1_0<TResult> <>c__DisplayClass1_;
DelegateResult<TResult> delegateOutcome2 = <>c__DisplayClass1_.delegateOutcome;
delegateOutcome = (DelegateResult<TResult>)new DelegateResult<TResult>(await action(cancellationToken).ConfigureAwait(continueOnCapturedContext));
cancellationToken.ThrowIfCancellationRequested();
if (!Enumerable.Any<ResultPredicate<TResult>>(shouldRetryResultPredicates, (Func<ResultPredicate<TResult>, bool>)((ResultPredicate<TResult> predicate) => predicate(((DelegateResult<TResult>)delegateOutcome).Result))))
return ((DelegateResult<TResult>)delegateOutcome).Result;
if (!(await policyState.CanRetryAsync((DelegateResult<TResult>)delegateOutcome, cancellationToken, continueOnCapturedContext).ConfigureAwait(continueOnCapturedContext)))
return ((DelegateResult<TResult>)delegateOutcome).Result;
} catch (Exception ex2) {
ex = ex2;
if (cancellationToken.IsCancellationRequested) {
if (ex is OperationCanceledException && ((OperationCanceledException)ex).CancellationToken == cancellationToken) {
Exception obj = ex2 as Exception;
if (obj == null)
throw ex2;
ExceptionDispatchInfo.Capture(obj).Throw();
}
cancellationToken.ThrowIfCancellationRequested();
}
if (!Enumerable.Any<ExceptionPredicate>(shouldRetryExceptionPredicates, (Func<ExceptionPredicate, bool>)((ExceptionPredicate predicate) => predicate(ex)))) {
Exception obj2 = ex2 as Exception;
if (obj2 == null)
throw ex2;
ExceptionDispatchInfo.Capture(obj2).Throw();
}
if (!(await policyState.CanRetryAsync(new DelegateResult<TResult>(ex), cancellationToken, continueOnCapturedContext).ConfigureAwait(continueOnCapturedContext))) {
Exception obj3 = ex2 as Exception;
if (obj3 == null)
throw ex2;
ExceptionDispatchInfo.Capture(obj3).Throw();
}
}
}
}
}
}