/// <summary>
        ///     Method called before the first operation execution
        /// </summary>
        protected virtual void OnFirstExecution()
        {
            if (Context?.Database.CurrentTransaction != null)
            {
                throw new InvalidOperationException(CoreStrings.ExecutionStrategyExistingTransaction(
                                                        GetType().Name,
                                                        nameof(DbContext) + "." + nameof(DbContext.Database) + "." + nameof(DatabaseFacade.CreateExecutionStrategy) + "()"));
            }

            ExceptionsEncountered.Clear();
        }
        private async Task <TResult> ExecuteImplementationAsync <TState, TResult>(
            Func <TState, CancellationToken, Task <TResult> > operation,
            Func <TState, CancellationToken, Task <ExecutionResult <TResult> > > verifySucceeded,
            TState state,
            CancellationToken cancellationToken)
        {
            while (true)
            {
                cancellationToken.ThrowIfCancellationRequested();

                TimeSpan?delay;
                try
                {
                    Suspended = true;
                    var result = await operation(state, cancellationToken);

                    Suspended = false;
                    return(result);
                }
                catch (Exception ex)
                {
                    Suspended = false;
                    if (verifySucceeded != null &&
                        CallOnWrappedException(ex, ShouldVerifySuccessOn))
                    {
                        var result = await ExecuteImplementationAsync(verifySucceeded, null, state, cancellationToken);

                        if (result.IsSuccessful)
                        {
                            return(result.Result);
                        }
                    }

                    if (!CallOnWrappedException(ex, ShouldRetryOn))
                    {
                        throw;
                    }

                    ExceptionsEncountered.Add(ex);

                    delay = GetNextDelay(ex);
                    if (delay == null)
                    {
                        throw new RetryLimitExceededException(CoreStrings.RetryLimitExceeded(MaxRetryCount, GetType().Name), ex);
                    }

                    OnRetry();
                }

                await Task.Delay(delay.Value, cancellationToken);
            }
        }
        private TResult ExecuteImplementation <TState, TResult>(
            Func <TState, TResult> operation,
            Func <TState, ExecutionResult <TResult> > verifySucceeded,
            TState state)
        {
            while (true)
            {
                TimeSpan?delay;
                try
                {
                    Suspended = true;
                    var result = operation(state);
                    Suspended = false;
                    return(result);
                }
                catch (Exception ex)
                {
                    Suspended = false;
                    if (verifySucceeded != null &&
                        CallOnWrappedException(ex, ShouldVerifySuccessOn))
                    {
                        var result = ExecuteImplementation(verifySucceeded, null, state);
                        if (result.IsSuccessful)
                        {
                            return(result.Result);
                        }
                    }

                    if (!CallOnWrappedException(ex, ShouldRetryOn))
                    {
                        throw;
                    }

                    ExceptionsEncountered.Add(ex);

                    delay = GetNextDelay(ex);
                    if (delay == null)
                    {
                        throw new RetryLimitExceededException(CoreStrings.RetryLimitExceeded(MaxRetryCount, GetType().Name), ex);
                    }

                    OnRetry();
                }

                using (var waitEvent = new ManualResetEventSlim(false))
                {
                    waitEvent.WaitHandle.WaitOne(delay.Value);
                }
            }
        }
Beispiel #4
0
        async Task <TResult> ExecuteImplementationAsync <TResult>(
            Func <CancellationToken,
                  Task <TResult> > operation,
            CancellationToken cancellationToken)
        {
            while (true)
            {
                cancellationToken.ThrowIfCancellationRequested();

                TimeSpan?delay;
                try
                {
                    Suspended = true;
                    var result = await operation(cancellationToken);

                    Suspended = false;
                    return(result);
                }
                catch (Exception ex)
                {
                    Suspended = false;

                    if (!ShouldRetryOn(ex))
                    {
                        throw;
                    }

                    ExceptionsEncountered.Add(ex);

                    delay = GetNextDelay(ex);
                    if (delay == null)
                    {
                        throw new RetryLimitExceededException(ex);
                    }

                    OnRetry();
                }

                await Task.Delay(delay.Value, cancellationToken);
            }
        }
Beispiel #5
0
        TResult ExecuteImplementation <TResult>(Func <TResult> operation)
        {
            while (true)
            {
                TimeSpan?delay;

                try
                {
                    Suspended = true;
                    var result = operation();
                    Suspended = false;
                    return(result);
                }
                catch (Exception ex)
                {
                    Suspended = false;
                    if (!ShouldRetryOn(ex))
                    {
                        throw;
                    }

                    ExceptionsEncountered.Add(ex);

                    delay = GetNextDelay(ex);
                    if (delay == null)
                    {
                        throw new RetryLimitExceededException(ex);
                    }

                    OnRetry();
                }

                using (var waitEvent = new ManualResetEventSlim(false))
                    waitEvent.WaitHandle.WaitOne(delay.Value);
            }
        }
 public new virtual TimeSpan?GetNextDelay(Exception lastException)
 {
     ExceptionsEncountered.Add(lastException);
     return(base.GetNextDelay(lastException));
 }
Beispiel #7
0
 /// <summary>
 ///     Method called before the first operation execution
 /// </summary>
 protected virtual void OnFirstExecution()
 {
     ExceptionsEncountered.Clear();
 }
 protected override TimeSpan?GetNextDelay(Exception lastException)
 {
     ExceptionsEncountered.Add(lastException);
     return(base.GetNextDelay(lastException));
 }