コード例 #1
0
ファイル: Retry.cs プロジェクト: nuscien/trivial
    /// <summary>
    /// Enables retry policy to process.
    /// </summary>
    /// <param name="cancellationToken">The optional cancellation token.</param>
    /// <returns>The processing retry result.</returns>
    public async Task <RetryResult> ProcessAsync(CancellationToken cancellationToken = default)
    {
        State = TaskStates.Initializing;
        var result = new RetryResult();
        var retry  = RetryPolicy?.CreateInstance() ?? new InternalRetryInstance();

        State = TaskStates.Working;
        while (true)
        {
            try
            {
                cancellationToken.ThrowIfCancellationRequested();
            }
            catch (OperationCanceledException)
            {
                State = TaskStates.Canceled;
                throw;
            }
            catch (ObjectDisposedException)
            {
                State = TaskStates.Canceled;
                throw;
            }

            try
            {
                await OnProcessAsync(cancellationToken);

                Processing?.Invoke(this, new RetryEventArgs(retry.ProcessTime));
                State = TaskStates.Done;
                result.Success();
                return(result);
            }
            catch (Exception ex)
            {
                State = TaskStates.WaitingToRetry;
                result.Fail(ex);
                try
                {
                    ex = ExceptionHandler.GetException(ex);
                }
                catch (Exception)
                {
                    State = TaskStates.Faulted;
                    throw;
                }

                if (ex != null)
                {
                    State = TaskStates.Faulted;
                    throw ex;
                }
            }

            var span = retry.Next();
            if (!span.HasValue)
            {
                State = TaskStates.Faulted;
                result.End();
                return(result);
            }

            await Task.Delay(span.Value, cancellationToken);

            State = TaskStates.Retrying;
        }
    }