/// <summary> /// Specify a fallback value if all the tries fail. /// </summary> /// <typeparam name="T"></typeparam> /// <param name="result"></param> /// <param name="defaultValue"></param> /// <returns></returns> public static RetryResult <T> WithFallBackValue <T>(this RetryResult <T> result, T defaultValue) { if (defaultValue == null) { throw new ArgumentNullException(nameof(defaultValue)); } if (!result.Successful) { try { result.ExecutedFallBack = true; result.Result = defaultValue; } catch (Exception ex) { result.FallBackException = ex; } } return(result); }
/// <summary> /// Configure a fallback function /// </summary> /// <typeparam name="T"></typeparam> /// <param name="result"></param> /// <param name="fallback"></param> /// <returns></returns> public static RetryResult <T> WithFallBack <T>(this RetryResult <T> result, Func <T> fallback) { if (fallback == null) { throw new ArgumentNullException(nameof(fallback)); } if (!result.Successful) { try { result.ExecutedFallBack = true; result.Result = fallback(); } catch (Exception ex) { result.FallBackException = ex; } } return(result); }
/// <summary> /// Retry a function n times or until successful asynchronously. /// </summary> /// <typeparam name="T"></typeparam> /// <param name="function"></param> /// <param name="config"></param> /// <returns></returns> static async Task <RetryResult <T> > RetryFuncAsync <T>(Func <Task <T> > function, RetryConfig config) { var retryInfo = new RetryInfo(); var result = new RetryResult <T>(default(T), retryInfo); var isOk = false; var retriesRemaining = config.MaxRetries; var timeoutAt = DateTime.Now.Add(config.TotalTimeout); bool hasTimeout = config.HasTimeout; while (!isOk && (retriesRemaining >= 0 || config.RetryForever) && (!hasTimeout || (config.HasTimeout && DateTime.Now < timeoutAt))) { result.RetryInfo.Executions++; try { result.Result = await function(); isOk = true; } catch (Exception ex) { result.RetryInfo.Exceptions.Add(ex); // Wait before retrying. if (config.WaitBetweenRetries > TimeSpan.Zero) { Thread.Sleep(config.WaitBetweenRetries); } } retriesRemaining--; } return(result); }