/// <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); } } }
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); } }
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)); }
/// <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)); }