/// <summary> /// Executes an action with many retries. /// </summary> /// /// <typeparam name="T1"> /// Type of the first argument. /// </typeparam> /// /// <typeparam name="T2"> /// Type of the second argument. /// </typeparam> /// /// <typeparam name="T3"> /// Type of the third argument. /// </typeparam> /// /// <typeparam name="T4"> /// Type of the fourth argument. /// </typeparam> /// /// <param name="action"> /// Action to execute. /// </param> /// /// <param name="arg1"> /// First action argument. /// </param> /// /// <param name="arg2"> /// Second action argument. /// </param> /// /// <param name="arg3"> /// Third action argument. /// </param> /// /// <param name="arg4"> /// Fourth action argument. /// </param> /// /// <param name="options"> /// Execution options. /// </param> /// /// <returns> /// True if the action has been executed; otherwise, false. /// </returns> /// /// <exception cref="AggregateException"> /// AggregateException if the action is not complete. /// </exception> public static bool ExecuteWithRetry <T1, T2, T3, T4>(this Action <T1, T2, T3, T4> action, T1 arg1, T2 arg2, T3 arg3, T4 arg4, ExecuteWithRetryOptions options = null) { if (options == null) { options = new ExecuteWithRetryOptions(); } int counter = 0; IList <Exception> exceptions = new List <Exception>(); do { try { action(arg1, arg2, arg3, arg4); options.IsComplete = true; } catch (Exception x) { DebugTraceException(x, counter); exceptions.Add(x); } finally { counter++; } if (!options.IsComplete && counter < options.RetryCounter) { Thread.Sleep(options.RetryDelay); } }while (!options.IsComplete && counter < options.RetryCounter); if (!exceptions.IsNullOrEmpty()) { ThrowException.ThrowAggregateException(exceptions); } return(options.IsComplete); }