Exemple #1
0
        /// <summary>
        /// Runs the given closure at least once, or retries as many times specified.
        /// </summary>
        /// /// <typeparam name="T">The type of the closure´s output.</typeparam>
        /// <param name="closure">The closure to run.</param>
        /// <param name="retriesAfterException">Times to retry the closure before allowing the exception to bubble up, if any.</param>
        /// <param name="retryConditionWhenNoException">Optional condition to check before an execution retry is performed.</param>
        /// <param name="betweenRetriesDelegate">Optional action delegate to execute between the closure´s executions.</param>
        /// <returns>The output of the specified closure.</returns>
        public static T Run <T>(Func <T> closure, int retriesAfterException = 3, Func <bool?> retryConditionWhenNoException = null, BetweenRetriesDelegate betweenRetriesDelegate = null)
        {
            T output = default(T);

            void internalClosure()
            {
                output = closure();
            }

            // By default, no condition in order to retry
            retryConditionWhenNoException = GetFuncOrDefault(retryConditionWhenNoException);

            // By default, nothing to do between retries
            betweenRetriesDelegate = GetDelegateOrDefault(betweenRetriesDelegate);

            RunImpl(internalClosure, retriesAfterException, 1, retryConditionWhenNoException, betweenRetriesDelegate);

            return(output);
        }
Exemple #2
0
        internal static void RunImpl(Action closure, int retriesAfterException, int currentTries, Func <bool?> retryConditionWhenNoException, BetweenRetriesDelegate betweenRetriesDelegate)
        {
            void DoRetry()
            {
                currentTries++;
                RunImpl(closure, retriesAfterException, currentTries, retryConditionWhenNoException, betweenRetriesDelegate);
            }

            try
            {
                closure();

                if (retryConditionWhenNoException() == true)
                {
                    betweenRetriesDelegate(currentTries);
                    DoRetry();
                }
            }
            catch
            {
                if (retriesAfterException == 0 || retriesAfterException == currentTries)
                {
                    throw;
                }
                else
                {
                    betweenRetriesDelegate(currentTries);
                    DoRetry();
                }
            }
        }
Exemple #3
0
        /// <summary>
        /// Runs the given closure at least once, or retries as many times specified.
        /// </summary>
        /// <param name="closure">The closure to run.</param>
        /// <param name="retriesAfterException">Times to retry the closure before allowing the exception to bubble up, if any.</param>
        /// <param name="retryConditionWhenNoException">Optional condition to check before an execution retry is performed.</param>
        /// <param name="betweenRetriesDelegate">Optional action delegate to execute between the closure´s executions.</param>
        public static void Run(Action closure, int retriesAfterException = 3, Func <bool?> retryConditionWhenNoException = null, BetweenRetriesDelegate betweenRetriesDelegate = null)
        {
            // By default, no condition in order to retry
            retryConditionWhenNoException = GetFuncOrDefault(retryConditionWhenNoException);

            // By default, nothing to do between retries
            betweenRetriesDelegate = GetDelegateOrDefault(betweenRetriesDelegate);

            RunImpl(closure, retriesAfterException, 1, retryConditionWhenNoException, betweenRetriesDelegate);
        }
Exemple #4
0
        /// <summary>
        /// Runs the given closure at least once, or retries as many times specified, sleeping for the given timespan between executions.
        /// </summary>
        /// <param name="closure">The closure to run.</param>
        /// <param name="betweenRetriesSpan">A TimeSpan of time to sleep between executions (if needed to retry).</param>
        /// <param name="retries">Times to retry the closure before allowing the exception to bubble up, if any.</param>
        /// <param name="retryCondition">Optional condition to check before an execution retry is performed.</param>
        public static void Run(Action closure, TimeSpan betweenRetriesSpan, int retries = 3, Func <bool?> retryCondition = null)
        {
            var betweenRetriesDelegate = new BetweenRetriesDelegate(x => Thread.Sleep(betweenRetriesSpan));

            RetryRunner.Run(closure, retries, retryCondition, betweenRetriesDelegate);
        }
Exemple #5
0
 internal static BetweenRetriesDelegate GetDelegateOrDefault(BetweenRetriesDelegate delegateInstance) =>
 delegateInstance ?? new BetweenRetriesDelegate(x => { });
Exemple #6
0
        /// <summary>
        /// Runs the given closure at least once, or retries as many times specified, sleeping for the given timespan between executions.
        /// </summary>
        /// <typeparam name="T">The type of the closure´s output.</typeparam>
        /// <param name="closure">The closure to run.</param>
        /// <param name="betweenRetriesSpan">A TimeSpan of time to sleep between executions (if needed to retry).</param>
        /// <param name="retriesAfterException">Times to retry the closure before allowing the exception to bubble up, if any.</param>
        /// <param name="retryConditionWhenNoException">Optional condition to check before an execution retry is performed.</param>
        /// <returns>The output of the specified closure.</returns>
        public static T Run <T>(Func <T> closure, TimeSpan betweenRetriesSpan, int retriesAfterException = 3, Func <bool?> retryConditionWhenNoException = null)
        {
            var betweenRetriesDelegate = new BetweenRetriesDelegate(x => Thread.Sleep(betweenRetriesSpan));

            return(RetryRunner.Run(closure, retriesAfterException, retryConditionWhenNoException, betweenRetriesDelegate));
        }