コード例 #1
0
        public static async Task <T> RetryAsync <T>(Func <Task <T> > asyncFunc, CancellationToken cancellationToken, IRetryStrategy strategy, IRetryPolicy policy, bool continueOnCapturedContext)
        {
            do
            {
                Exception exception;

                try
                {
                    return(await asyncFunc().ConfigureAwait(continueOnCapturedContext));
                }
                catch (Exception ex)
                {
                    exception = ex;
                }

                var delay = strategy.PrepareToRetry(exception);

                if (!WillRetry(exception, cancellationToken, strategy, policy))
                {
                    throw exception;
                }

                strategy.OnRetrying(new RetryEventArgs(exception, delay));

                if (delay != TimeSpan.Zero)
                {
                    if (SleepService != null)
                    {
                        SleepService.Sleep(delay);
                    }
                }
            }while (true);
        }
コード例 #2
0
        public static T Retry <T>(Func <T> func, CancellationToken cancellationToken, IRetryStrategy strategy, IRetryPolicy policy)
        {
            do
            {
                try
                {
                    return(func());
                }
                catch (Exception exception)
                {
                    var delay = strategy.PrepareToRetry(exception);

                    if (!WillRetry(exception, cancellationToken, strategy, policy))
                    {
                        throw;
                    }

                    strategy.OnRetrying(new RetryEventArgs(exception, delay));

                    if (delay != TimeSpan.Zero)
                    {
                        if (SleepService != null)
                        {
                            SleepService.Sleep(delay);
                        }
                    }
                }
            }while (true);
        }
コード例 #3
0
        /// <summary>
        /// Retries an asynchronous operation with cancellation.
        /// </summary>
        /// <param name="asyncFunc">The asynchronous function to retry.</param>
        /// <param name="cancellationToken">The token with which to signal cancellation.</param>
        /// <param name="strategy">The retry strategy.</param>
        /// <param name="policy">The retry policy.</param>
        /// <param name="continueOnCapturedContext">Whether to continue on the captured context.</param>
        /// <returns>A task which completes when the operation completes.</returns>
        public static async Task RetryAsync(Func <Task> asyncFunc, CancellationToken cancellationToken, IRetryStrategy strategy, IRetryPolicy policy, bool continueOnCapturedContext)
        {
            if (asyncFunc is null)
            {
                throw new ArgumentNullException(nameof(asyncFunc));
            }

            if (strategy is null)
            {
                throw new ArgumentNullException(nameof(strategy));
            }

            if (policy is null)
            {
                throw new ArgumentNullException(nameof(policy));
            }

            while (true)
            {
                Exception exception;

                try
                {
                    await asyncFunc().ConfigureAwait(continueOnCapturedContext);

                    return;
                }
                catch (Exception ex)
                {
                    exception = ex;
                }

                TimeSpan delay = strategy.PrepareToRetry(exception);

                if (!WillRetry(exception, cancellationToken, strategy, policy))
                {
                    throw exception;
                }

                strategy.OnRetrying(new RetryEventArgs(exception, delay));

                if (delay != TimeSpan.Zero)
                {
                    await SleepService.Instance.SleepAsync(delay).ConfigureAwait(continueOnCapturedContext);
                }
            }
        }
コード例 #4
0
        /// <summary>
        /// Handles retrying a given task.
        /// </summary>
        /// <param name="task">The task that is currently executing.</param>
        /// <param name="createTask">A function that can create a new task to retry the operation.</param>
        /// <param name="strategy">The retry strategy.</param>
        /// <param name="policy">The retry policy.</param>
        /// <returns>A new task which is retrying the existing task, or the original task if retry is not required.</returns>
        /// <remarks>
        /// <para>
        /// If the task completed successfully, then retry is not required and the original task is returned.
        /// </para>
        /// <para>
        /// It the task failed, then this method uses the strategy to determine whether it will retry based on the exception on the original task.
        /// If it will retry, it raises the <see cref="IRetryStrategy.Retrying"/> event, then delays for the calculated time using the Sleep service.
        /// It then creates a new task using the <c>createTask</c> function provided, and runs the task synchronously.
        /// </para>
        /// </remarks>
        internal static Task HandleRetry(Task task, Func <Task> createTask, IRetryStrategy strategy, IRetryPolicy policy)
        {
            if (task is null)
            {
                throw new ArgumentNullException(nameof(task));
            }

            if (createTask is null)
            {
                throw new ArgumentNullException(nameof(createTask));
            }

            if (strategy is null)
            {
                throw new ArgumentNullException(nameof(strategy));
            }

            if (policy is null)
            {
                throw new ArgumentNullException(nameof(policy));
            }

            while (task.Exception != null)
            {
                TimeSpan delay = strategy.PrepareToRetry(task.Exception);

                if (!WillRetry(task, strategy, policy))
                {
                    break;
                }

                strategy.OnRetrying(new RetryEventArgs(task.Exception, delay));

                if (delay != TimeSpan.Zero)
                {
                    SleepService.Instance.Sleep(delay);
                }

                task = createTask();
                task.RunSynchronously();
            }

            return(task);
        }
コード例 #5
0
        /// <summary>
        ///  Retries an operation with cancellation.
        /// </summary>
        /// <param name="func">The operatoin to retry.</param>
        /// <param name="cancellationToken">The token with which cancellation is signalled.</param>
        /// <param name="strategy">The retry strategy.</param>
        /// <param name="policy">The retry policy.</param>
        /// <remarks>This function does not continue on the captured context. See the overload if you want to override this default behaviour.</remarks>
        public static void Retry(Action func, CancellationToken cancellationToken, IRetryStrategy strategy, IRetryPolicy policy)
        {
            if (func is null)
            {
                throw new ArgumentNullException(nameof(func));
            }

            if (strategy is null)
            {
                throw new ArgumentNullException(nameof(strategy));
            }

            if (policy is null)
            {
                throw new ArgumentNullException(nameof(policy));
            }

            while (true)
            {
                try
                {
                    func();
                    return;
                }
                catch (Exception exception)
                {
                    TimeSpan delay = strategy.PrepareToRetry(exception);

                    if (!WillRetry(exception, cancellationToken, strategy, policy))
                    {
                        throw;
                    }

                    strategy.OnRetrying(new RetryEventArgs(exception, delay));

                    if (delay != TimeSpan.Zero)
                    {
                        SleepService.Instance.Sleep(delay);
                    }
                }
            }
        }