/// <summary> /// Retries while the given method has an exception and returns the value from the method. /// </summary> public static RetryResult <T> WhileException <T>(Func <T> retryMethod, TimeSpan?timeout = null, TimeSpan?interval = null, bool throwOnTimeout = false, string timeoutMessage = null) { var returnValue = default(T); var result = WhileTrue(() => { returnValue = retryMethod(); return(false); }, timeout, interval, ignoreException: true, throwOnTimeout: throwOnTimeout, timeoutMessage: timeoutMessage); var newResult = new RetryResult <T>(); if (result.HadException) { newResult.SetException(result.LastException); } newResult.Finish(returnValue, result.TimedOut); return(newResult); }
/// <summary> /// Retries while the given method evaluates to true and returns the value from the method. /// If it fails, it returns the default of <typeparamref name="T"/>. /// </summary> /// <typeparam name="T">The type of the return value.</typeparam> /// <param name="retryMethod">The method which is retried.</param> /// <param name="checkMethod">The method which is used to decide if a retry is needed or if the value is correct.</param> /// <param name="timeout">The timeout when the retry aborts.</param> /// <param name="interval">The interval of retries.</param> /// <param name="throwOnTimeout">A flag indicating if it should throw on timeout.</param> /// <param name="ignoreException">A flag indicating if it should retry on an exception.</param> /// <param name="timeoutMessage">The message that should be added to the timeout exception in case a timeout occurs.</param> /// <param name="lastValueOnTimeout">A flag indicating if the last value should be returned on timeout. Returns the default if the value could never be fetched.</param> /// <param name="defaultOnTimeout">Allows to define a default value in case of a timeout.</param> /// <returns>The value from <paramref name="retryMethod"/> or the default of <typeparamref name="T"/>.</returns> public static RetryResult <T> While <T>(Func <T> retryMethod, Func <T, bool> checkMethod, TimeSpan?timeout = null, TimeSpan?interval = null, bool throwOnTimeout = false, bool ignoreException = false, string timeoutMessage = null, bool lastValueOnTimeout = false, T defaultOnTimeout = default(T)) { var retryResult = new RetryResult <T>(); timeout = timeout ?? DefaultTimeout; interval = interval ?? DefaultInterval; var startTime = DateTime.UtcNow; Exception lastException = null; T lastValue = defaultOnTimeout; do { retryResult.Iterations++; try { lastValue = retryMethod(); if (!checkMethod(lastValue)) { return(retryResult.Finish(lastValue)); } } catch (Exception ex) { if (!ignoreException) { throw; } lastException = ex; retryResult.SetException(ex); } Thread.Sleep(interval.Value); } while (!IsTimeoutReached(startTime, timeout.Value)); if (throwOnTimeout) { timeoutMessage = timeoutMessage ?? "Timeout occurred in retry"; throw new TimeoutException(timeoutMessage, lastException); } return(retryResult.Finish(lastValueOnTimeout ? lastValue : defaultOnTimeout, true)); }