private async Task WaitBeforeRetry(int currentRetry, RetryOptions retryOptions) { if (currentRetry > 1 && retryOptions.EnableLogging) { _logger?.LogInformation( $"Retrying <Attempt:{currentRetry}> " + $"Options:{retryOptions.Attempts}" + $"/{retryOptions.EnableLogging}" + $"/{retryOptions.DelayBetweenRetries}" + $"/{retryOptions.DelayBeforeFirstTry}"); } await Task.Delay(retryOptions.DelayBeforeFirstTry); }
/// <summary> /// An extension method to provide Retry functionality for any asynchronous TASK /// </summary> /// <param name="task">The extension target type</param> /// <param name="retryOptions">The options for the retry algorithm</param> /// <returns>a task responsible for the retry operation</returns> public static async Task <T> Retry <T>(this Task <T> task, RetryOptions retryOptions = null) { retryOptions ??= new RetryOptions(); var tasks = new Queue <Task <T> >(); for (int i = 0; i < retryOptions.Attempts; i++) { tasks.Enqueue(task); } var currentRetry = 1; for (;;) { try { if (currentRetry > 1 && retryOptions.EnableLogging) { Trace.TraceInformation($"Retrying attempt {currentRetry}"); } await Task.Delay(retryOptions.DelayBeforeFirstTry); var result = await tasks.Dequeue(); return(result); } catch (Exception ex) { if (retryOptions.EnableLogging) { Trace.TraceError( $"Operation Exception see the inner exception for the details ----> " + $"Message: {ex.Message} " + $"Stack: {ex.StackTrace} "); } currentRetry++; if (currentRetry > retryOptions.Attempts || retryOptions.DoNotRetryOnTheseExceptionTypes.Any(z => z == ex.GetType())) { throw; } } await Task.Delay(retryOptions.DelayBetweenRetries); } }
/// <summary> /// An extension method to provide Retry functionality for any asynchronous TASK /// </summary> /// <param name="task">The extension target type</param> /// <param name="retryOptions">The options for the retry algorithm</param> /// <returns>a task responsible for the retry operation</returns> public static async Task Retry(this Action action, RetryOptions retryOptions = null) { var tasks = new Queue <Action>(); tasks.Enqueue(action); tasks.Enqueue(action); retryOptions ??= new RetryOptions(); var currentRetry = 1; for (;;) { try { if (currentRetry > 1 && retryOptions.EnableLogging) { Trace.TraceInformation($"Retrying attempt {currentRetry}"); } await Task.Delay(retryOptions.DelayBeforeFirstTry); await new Task(tasks.Dequeue()); break; } catch (Exception ex) { if (retryOptions.EnableLogging) { Trace.TraceError( $"Operation Exception see the inner exception for the details ----> " + $"Message: {ex.Message} " + $"Stack: {ex.StackTrace} "); } currentRetry++; if (currentRetry > retryOptions.Attempts || retryOptions.DoNotRetryOnTheseExceptionTypes.Any(z => z == ex.GetType())) { throw; } } await Task.Delay(retryOptions.DelayBetweenRetries); } }
/// <summary> /// Will retry the given <see cref="Action"/> synchronously /// </summary> /// <param name="action">The desired action to be retried with the specified <see cref="RetryOptions"/></param> /// <param name="retryOptions"><see cref="RetryOptions"/></param> /// <returns></returns> public void Retry(Action action, RetryOptions retryOptions = null) { retryOptions ??= new RetryOptions(); var currentRetry = 1; for (;;) { try { if (currentRetry > 1 && retryOptions.EnableLogging) { _logger?.LogInformation($"Retrying attempt {currentRetry} ... "); } Task.Delay(retryOptions.DelayBeforeFirstTry).GetAwaiter().GetResult(); action.Invoke(); break; } catch (Exception ex) { if (retryOptions.EnableLogging) { LogException(currentRetry, ex); } currentRetry++; if (currentRetry > retryOptions.Attempts || retryOptions.DoNotRetryOnTheseExceptionTypes.Any(z => z == ex.GetType())) { throw; } } Task.Delay(retryOptions.DelayBetweenRetries).GetAwaiter().GetResult(); } }