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

Policy<TResult>

public abstract class Policy<TResult> : PolicyBase, IAsyncPolicy<TResult>, IsPolicy, ISyncPolicy<TResult>
Transient fault handling policies that can be applied to delegates returning results of type TResult
using Polly.Utilities; using Polly.Wrap; using System; using System.Collections.Generic; using System.Diagnostics; using System.Linq; using System.Threading; using System.Threading.Tasks; namespace Polly { public abstract class Policy<TResult> : PolicyBase, IAsyncPolicy<TResult>, IsPolicy, ISyncPolicy<TResult> { private readonly Func<Func<Context, CancellationToken, Task<TResult>>, Context, CancellationToken, bool, Task<TResult>> _asyncExecutionPolicy; private readonly Func<Func<Context, CancellationToken, TResult>, Context, CancellationToken, TResult> _executionPolicy; internal IEnumerable<ResultPredicate<TResult>> ResultPredicates { get; } [DebuggerStepThrough] public Task<TResult> ExecuteAsync(Func<Task<TResult>> action) { return ExecuteAsync((Context ctx, CancellationToken ct) => action(), new Context(), CancellationToken.None, PolicyBase.DefaultContinueOnCapturedContext); } [DebuggerStepThrough] public Task<TResult> ExecuteAsync(Func<Context, Task<TResult>> action, IDictionary<string, object> contextData) { return ExecuteAsync((Context ctx, CancellationToken ct) => action(ctx), new Context(contextData), CancellationToken.None, PolicyBase.DefaultContinueOnCapturedContext); } [DebuggerStepThrough] public Task<TResult> ExecuteAsync(Func<Context, Task<TResult>> action, Context context) { return ExecuteAsync((Context ctx, CancellationToken ct) => action(ctx), context, CancellationToken.None, PolicyBase.DefaultContinueOnCapturedContext); } [DebuggerStepThrough] public Task<TResult> ExecuteAsync(Func<CancellationToken, Task<TResult>> action, CancellationToken cancellationToken) { return ExecuteAsync((Context ctx, CancellationToken ct) => action(ct), new Context(), cancellationToken, PolicyBase.DefaultContinueOnCapturedContext); } [DebuggerStepThrough] public Task<TResult> ExecuteAsync(Func<CancellationToken, Task<TResult>> action, CancellationToken cancellationToken, bool continueOnCapturedContext) { return ExecuteAsync((Context ctx, CancellationToken ct) => action(ct), new Context(), cancellationToken, continueOnCapturedContext); } [DebuggerStepThrough] public Task<TResult> ExecuteAsync(Func<Context, CancellationToken, Task<TResult>> action, IDictionary<string, object> contextData, CancellationToken cancellationToken) { return ExecuteAsync(action, new Context(contextData), cancellationToken, PolicyBase.DefaultContinueOnCapturedContext); } [DebuggerStepThrough] public Task<TResult> ExecuteAsync(Func<Context, CancellationToken, Task<TResult>> action, Context context, CancellationToken cancellationToken) { return ExecuteAsync(action, context, cancellationToken, PolicyBase.DefaultContinueOnCapturedContext); } [DebuggerStepThrough] public Task<TResult> ExecuteAsync(Func<Context, CancellationToken, Task<TResult>> action, IDictionary<string, object> contextData, CancellationToken cancellationToken, bool continueOnCapturedContext) { return ExecuteAsync(action, new Context(contextData), cancellationToken, continueOnCapturedContext); } [DebuggerStepThrough] public Task<TResult> ExecuteAsync(Func<Context, CancellationToken, Task<TResult>> action, Context context, CancellationToken cancellationToken, bool continueOnCapturedContext) { if (context == null) throw new ArgumentNullException("context"); SetPolicyContext(context); return ExecuteAsyncInternal(action, context, cancellationToken, continueOnCapturedContext); } [DebuggerStepThrough] public Task<PolicyResult<TResult>> ExecuteAndCaptureAsync(Func<Task<TResult>> action) { return ExecuteAndCaptureAsync((Context ctx, CancellationToken ct) => action(), new Context(), CancellationToken.None, PolicyBase.DefaultContinueOnCapturedContext); } [DebuggerStepThrough] public Task<PolicyResult<TResult>> ExecuteAndCaptureAsync(Func<Context, Task<TResult>> action, IDictionary<string, object> contextData) { return ExecuteAndCaptureAsync((Context ctx, CancellationToken ct) => action(ctx), new Context(contextData), CancellationToken.None, PolicyBase.DefaultContinueOnCapturedContext); } [DebuggerStepThrough] public Task<PolicyResult<TResult>> ExecuteAndCaptureAsync(Func<Context, Task<TResult>> action, Context context) { return ExecuteAndCaptureAsync((Context ctx, CancellationToken ct) => action(ctx), context, CancellationToken.None, PolicyBase.DefaultContinueOnCapturedContext); } [DebuggerStepThrough] public Task<PolicyResult<TResult>> ExecuteAndCaptureAsync(Func<CancellationToken, Task<TResult>> action, CancellationToken cancellationToken) { return ExecuteAndCaptureAsync((Context ctx, CancellationToken ct) => action(ct), new Context(), cancellationToken, PolicyBase.DefaultContinueOnCapturedContext); } [DebuggerStepThrough] public Task<PolicyResult<TResult>> ExecuteAndCaptureAsync(Func<CancellationToken, Task<TResult>> action, CancellationToken cancellationToken, bool continueOnCapturedContext) { return ExecuteAndCaptureAsync((Context ctx, CancellationToken ct) => action(ct), new Context(), cancellationToken, continueOnCapturedContext); } [DebuggerStepThrough] public Task<PolicyResult<TResult>> ExecuteAndCaptureAsync(Func<Context, CancellationToken, Task<TResult>> action, IDictionary<string, object> contextData, CancellationToken cancellationToken) { return ExecuteAndCaptureAsync(action, new Context(contextData), cancellationToken, PolicyBase.DefaultContinueOnCapturedContext); } [DebuggerStepThrough] public Task<PolicyResult<TResult>> ExecuteAndCaptureAsync(Func<Context, CancellationToken, Task<TResult>> action, Context context, CancellationToken cancellationToken) { return ExecuteAndCaptureAsync(action, context, cancellationToken, PolicyBase.DefaultContinueOnCapturedContext); } [DebuggerStepThrough] public Task<PolicyResult<TResult>> ExecuteAndCaptureAsync(Func<Context, CancellationToken, Task<TResult>> action, IDictionary<string, object> contextData, CancellationToken cancellationToken, bool continueOnCapturedContext) { return ExecuteAndCaptureAsync(action, new Context(contextData), cancellationToken, continueOnCapturedContext); } public async Task<PolicyResult<TResult>> ExecuteAndCaptureAsync(Func<Context, CancellationToken, Task<TResult>> action, Context context, CancellationToken cancellationToken, bool continueOnCapturedContext) { if (this._asyncExecutionPolicy == null) throw new InvalidOperationException("Please use asynchronous-defined policies when calling asynchronous ExecuteAsync (and similar) methods."); if (context != null) try { TResult result = await this.ExecuteAsync(action, context, cancellationToken, continueOnCapturedContext).ConfigureAwait(continueOnCapturedContext); if (Enumerable.Any<ResultPredicate<TResult>>(this.ResultPredicates, (Func<ResultPredicate<TResult>, bool>)((ResultPredicate<TResult> predicate) => predicate(result)))) return PolicyResult<TResult>.Failure(result, context); return PolicyResult<TResult>.Successful(result, context); } catch (Exception exception) { return PolicyResult<TResult>.Failure(exception, Policy<TResult>.GetExceptionType(base.ExceptionPredicates, exception), context); } throw new ArgumentNullException("context"); } public static PolicyBuilder<TResult> Handle<TException>() where TException : Exception { return new PolicyBuilder<TResult>((ExceptionPredicate)delegate(Exception exception) { if (!(exception is TException)) return null; return exception; }); } public static PolicyBuilder<TResult> Handle<TException>(Func<TException, bool> exceptionPredicate) where TException : Exception { return new PolicyBuilder<TResult>((ExceptionPredicate)delegate(Exception exception) { TException arg; if ((arg = (exception as TException)) == null || !exceptionPredicate(arg)) return null; return exception; }); } public static PolicyBuilder<TResult> HandleInner<TException>() where TException : Exception { return new PolicyBuilder<TResult>(PolicyBuilder.HandleInner((Exception ex) => ex is TException)); } public static PolicyBuilder<TResult> HandleInner<TException>(Func<TException, bool> exceptionPredicate) where TException : Exception { return new PolicyBuilder<TResult>(PolicyBuilder.HandleInner(delegate(Exception ex) { TException arg; if ((arg = (ex as TException)) != null) return exceptionPredicate(arg); return false; })); } public static PolicyBuilder<TResult> HandleResult(Func<TResult, bool> resultPredicate) { return new PolicyBuilder<TResult>(resultPredicate); } public static PolicyBuilder<TResult> HandleResult(TResult result) { return HandleResult(delegate(TResult r) { if (r == null || !r.Equals(result)) { if (r == null) return result == null; return false; } return true; }); } public Policy<TResult> WithPolicyKey(string policyKey) { if (policyKeyInternal != null) throw PolicyBase.PolicyKeyMustBeImmutableException; policyKeyInternal = policyKey; return this; } ISyncPolicy<TResult> ISyncPolicy<TResult>.WithPolicyKey(string policyKey) { if (policyKeyInternal != null) throw PolicyBase.PolicyKeyMustBeImmutableException; policyKeyInternal = policyKey; return this; } IAsyncPolicy<TResult> IAsyncPolicy<TResult>.WithPolicyKey(string policyKey) { if (policyKeyInternal != null) throw PolicyBase.PolicyKeyMustBeImmutableException; policyKeyInternal = policyKey; return this; } protected Policy(Func<Func<Context, CancellationToken, Task<TResult>>, Context, CancellationToken, bool, Task<TResult>> asyncExecutionPolicy, IEnumerable<ExceptionPredicate> exceptionPredicates, IEnumerable<ResultPredicate<TResult>> resultPredicates) { if (asyncExecutionPolicy == null) throw new ArgumentNullException("asyncExecutionPolicy"); _asyncExecutionPolicy = asyncExecutionPolicy; base.ExceptionPredicates = (exceptionPredicates ?? PredicateHelper.EmptyExceptionPredicates); ResultPredicates = (resultPredicates ?? PredicateHelper<TResult>.EmptyResultPredicates); } [DebuggerStepThrough] internal Task<TResult> ExecuteAsyncInternal(Func<Context, CancellationToken, Task<TResult>> action, Context context, CancellationToken cancellationToken, bool continueOnCapturedContext) { if (_asyncExecutionPolicy == null) throw new InvalidOperationException("Please use asynchronous-defined policies when calling asynchronous ExecuteAsync (and similar) methods."); return _asyncExecutionPolicy(action, context, cancellationToken, continueOnCapturedContext); } [DebuggerStepThrough] public TResult Execute(Func<TResult> action) { return Execute((Context ctx, CancellationToken ct) => action(), new Context(), PolicyBase.DefaultCancellationToken); } [DebuggerStepThrough] public TResult Execute(Func<Context, TResult> action, IDictionary<string, object> contextData) { return Execute((Context ctx, CancellationToken ct) => action(ctx), new Context(contextData), PolicyBase.DefaultCancellationToken); } [DebuggerStepThrough] public TResult Execute(Func<Context, TResult> action, Context context) { return Execute((Context ctx, CancellationToken ct) => action(ctx), context, PolicyBase.DefaultCancellationToken); } [DebuggerStepThrough] public TResult Execute(Func<CancellationToken, TResult> action, CancellationToken cancellationToken) { return Execute((Context ctx, CancellationToken ct) => action(ct), new Context(), cancellationToken); } [DebuggerStepThrough] public TResult Execute(Func<Context, CancellationToken, TResult> action, IDictionary<string, object> contextData, CancellationToken cancellationToken) { return Execute(action, new Context(contextData), cancellationToken); } [DebuggerStepThrough] public TResult Execute(Func<Context, CancellationToken, TResult> action, Context context, CancellationToken cancellationToken) { if (context == null) throw new ArgumentNullException("context"); SetPolicyContext(context); return ExecuteInternal(action, context, cancellationToken); } [DebuggerStepThrough] public PolicyResult<TResult> ExecuteAndCapture(Func<TResult> action) { return ExecuteAndCapture((Context ctx, CancellationToken ct) => action(), new Context(), PolicyBase.DefaultCancellationToken); } [DebuggerStepThrough] public PolicyResult<TResult> ExecuteAndCapture(Func<Context, TResult> action, IDictionary<string, object> contextData) { return ExecuteAndCapture((Context ctx, CancellationToken ct) => action(ctx), new Context(contextData), PolicyBase.DefaultCancellationToken); } [DebuggerStepThrough] public PolicyResult<TResult> ExecuteAndCapture(Func<Context, TResult> action, Context context) { return ExecuteAndCapture((Context ctx, CancellationToken ct) => action(ctx), context, PolicyBase.DefaultCancellationToken); } [DebuggerStepThrough] public PolicyResult<TResult> ExecuteAndCapture(Func<CancellationToken, TResult> action, CancellationToken cancellationToken) { return ExecuteAndCapture((Context ctx, CancellationToken ct) => action(ct), new Context(), cancellationToken); } [DebuggerStepThrough] public PolicyResult<TResult> ExecuteAndCapture(Func<Context, CancellationToken, TResult> action, IDictionary<string, object> contextData, CancellationToken cancellationToken) { return ExecuteAndCapture(action, new Context(contextData), cancellationToken); } [DebuggerStepThrough] public PolicyResult<TResult> ExecuteAndCapture(Func<Context, CancellationToken, TResult> action, Context context, CancellationToken cancellationToken) { if (_executionPolicy == null) throw new InvalidOperationException("Please use the synchronous-defined policies when calling the synchronous Execute (and similar) methods."); if (context != null) try { TResult result = Execute(action, context, cancellationToken); if (!Enumerable.Any<ResultPredicate<TResult>>(ResultPredicates, (Func<ResultPredicate<TResult>, bool>)((ResultPredicate<TResult> predicate) => predicate(result)))) return PolicyResult<TResult>.Successful(result, context); return PolicyResult<TResult>.Failure(result, context); } catch (Exception exception) { return PolicyResult<TResult>.Failure(exception, GetExceptionType(base.ExceptionPredicates, exception), context); } throw new ArgumentNullException("context"); } internal static ExceptionType GetExceptionType(IEnumerable<ExceptionPredicate> exceptionPredicates, Exception exception) { return Policy.GetExceptionType(exceptionPredicates, exception); } protected Policy(Func<Func<Context, CancellationToken, TResult>, Context, CancellationToken, TResult> executionPolicy, IEnumerable<ExceptionPredicate> exceptionPredicates, IEnumerable<ResultPredicate<TResult>> resultPredicates) { if (executionPolicy == null) throw new ArgumentNullException("executionPolicy"); _executionPolicy = executionPolicy; base.ExceptionPredicates = (exceptionPredicates ?? PredicateHelper.EmptyExceptionPredicates); ResultPredicates = (resultPredicates ?? PredicateHelper<TResult>.EmptyResultPredicates); } [DebuggerStepThrough] internal TResult ExecuteInternal(Func<Context, CancellationToken, TResult> action, Context context, CancellationToken cancellationToken) { if (_executionPolicy == null) throw new InvalidOperationException("Please use the synchronous-defined policies when calling the synchronous Execute (and similar) methods."); return _executionPolicy(action, context, cancellationToken); } public PolicyWrap<TResult> Wrap(ISyncPolicy innerPolicy) { if (innerPolicy == null) throw new ArgumentNullException("innerPolicy"); return new PolicyWrap<TResult>((Func<Context, CancellationToken, TResult> func, Context context, CancellationToken cancellationtoken) => PolicyWrapEngine.Implementation<TResult>(func, context, cancellationtoken, (ISyncPolicy<TResult>)this, innerPolicy), this, innerPolicy); } public PolicyWrap<TResult> Wrap(ISyncPolicy<TResult> innerPolicy) { if (innerPolicy == null) throw new ArgumentNullException("innerPolicy"); return new PolicyWrap<TResult>((Func<Context, CancellationToken, TResult> func, Context context, CancellationToken cancellationtoken) => PolicyWrapEngine.Implementation<TResult>(func, context, cancellationtoken, (ISyncPolicy<TResult>)this, innerPolicy), this, innerPolicy); } public PolicyWrap<TResult> WrapAsync(IAsyncPolicy innerPolicy) { if (innerPolicy == null) throw new ArgumentNullException("innerPolicy"); return new PolicyWrap<TResult>((Func<Context, CancellationToken, Task<TResult>> func, Context context, CancellationToken cancellationtoken, bool continueOnCapturedContext) => PolicyWrapEngine.ImplementationAsync<TResult>(func, context, cancellationtoken, continueOnCapturedContext, (IAsyncPolicy<TResult>)this, innerPolicy), this, innerPolicy); } public PolicyWrap<TResult> WrapAsync(IAsyncPolicy<TResult> innerPolicy) { if (innerPolicy == null) throw new ArgumentNullException("innerPolicy"); return new PolicyWrap<TResult>((Func<Context, CancellationToken, Task<TResult>> func, Context context, CancellationToken cancellationtoken, bool continueOnCapturedContext) => PolicyWrapEngine.ImplementationAsync<TResult>(func, context, cancellationtoken, continueOnCapturedContext, (IAsyncPolicy<TResult>)this, innerPolicy), this, innerPolicy); } } }