public static TInterface Create <TInterface>(TInterface instance, RetryOptions options, IRetryExceptionTester retryExceptionTester = null, IEnumerable <Type> exceptionWhiteList = null, IEnumerable <Type> exceptionBlackList = null) where TInterface : class { var result = Create <TInterface, RetryProxy>(); var proxy = (result as RetryProxy); proxy._instance = instance ?? throw new ArgumentNullException(nameof(instance)); proxy._options = options ?? throw new ArgumentNullException(nameof(options)); proxy._retryExceptionTester = retryExceptionTester; proxy._exceptionWhiteList = exceptionWhiteList; proxy._exceptionBlackList = exceptionBlackList; return(result); }
public static void SetDefaultOptions(RetryOptions options) { _defaultRetryOptions = options; }
public static void Invoke(RetryOptions options, Action action, IRetryExceptionTester retryExceptionTester = null, IEnumerable <Type> exceptionWhiteList = null, IEnumerable <Type> exceptionBlackList = null) { if (action == null) { throw new ArgumentNullException(nameof(action)); } if (options == null) { throw new ArgumentNullException(nameof(options)); } List <Exception> exceptions = null; var waitTime = options.InitialInterval; var currentAttempt = 1; Exception exception = null; var stopwatch = new Stopwatch(); stopwatch.Start(); var complete = false; while (!complete) { try { action(); complete = true; } catch (TargetInvocationException ex) { exception = ex.InnerException; } catch (AggregateException ex) { exception = ex.GetBaseException(); } catch (Exception ex) { exception = ex; } // test the exception for can retry, exceeded max retry, and timeout if (exception != null) { if (exceptions == null) { exceptions = new List <Exception>(); } var retryException = TestException(options, retryExceptionTester, exceptionWhiteList, exceptionBlackList, exception, currentAttempt++, stopwatch.Elapsed, exceptions); if (retryException != null) { throw retryException; } } //reset exception for next attempt exception = null; // wait a bit before trying again Thread.Sleep(waitTime); // ratcheting up - allows wait times up to ~10 seconds per try waitTime = TimeSpan.FromMilliseconds(waitTime.TotalMilliseconds <= 110 ? waitTime.TotalMilliseconds * 1.25 : waitTime.TotalMilliseconds); } }
public static T Invoke <T>(RetryOptions options, Func <T> function, IRetryExceptionTester retryExceptionTester = null, IEnumerable <Type> exceptionWhiteList = null, IEnumerable <Type> exceptionBlackList = null) { if (function == null) { throw new ArgumentNullException(nameof(function)); } if (options == null) { throw new ArgumentNullException(nameof(options)); } var isAwaitable = function.Method.ReturnType.GetMethod(nameof(Task.GetAwaiter)) != null; if (isAwaitable) { throw new NotSupportedException("Use InvokeAsync<T> instead."); } var result = default(T); List <Exception> exceptions = null; var waitTime = options.InitialInterval; var currentAttempt = 1; Exception exception = null; var stopwatch = new Stopwatch(); stopwatch.Start(); var complete = false; while (!complete) { try { result = function(); complete = true; } catch (TargetInvocationException ex) { exception = ex.InnerException; } catch (AggregateException ex) { exception = ex.GetBaseException(); } catch (Exception ex) { exception = ex; } // test the exception for can retry, exceeded max retry, and timeout if (exception != null) { if (exceptions == null) { exceptions = new List <Exception>(); } var retryException = TestException(options, retryExceptionTester, exceptionWhiteList, exceptionBlackList, exception, currentAttempt++, stopwatch.Elapsed, exceptions); if (retryException != null) { throw retryException; } } //reset exception for next attempt exception = null; // wait a bit before trying again Thread.Sleep(waitTime); // ratcheting up - allows wait times up to ~10 seconds per try waitTime = TimeSpan.FromMilliseconds(waitTime.TotalMilliseconds <= 110 ? waitTime.TotalMilliseconds * 1.25 : waitTime.TotalMilliseconds); } return(result); }