public void PropertiesAreSetByConstrutor() { var condition = new RetryCondition(true, TimeSpan.FromSeconds(1)); Assert.Equal(true, condition.RetryAllowed); Assert.Equal(TimeSpan.FromSeconds(1), condition.DelayBeforeRetry); condition = new RetryCondition(false, TimeSpan.Zero); Assert.Equal(false, condition.RetryAllowed); Assert.Equal(TimeSpan.Zero, condition.DelayBeforeRetry); }
public virtual TResult ExecuteAction <TResult>(Func <TResult> func) { Guard.ArgumentNotNull(func, "func"); int retryCount = 0; TimeSpan delay = TimeSpan.Zero; Exception lastError; var shouldRetry = this.RetryStrategy.GetShouldRetryHandler(); for (;;) { lastError = null; try { return(func()); } catch (Exception ex) { lastError = ex; if (!(this.ErrorDetectionStrategy.IsTransient(lastError))) { throw; } RetryCondition condition = shouldRetry(retryCount++, lastError); if (!condition.RetryAllowed) { throw; } delay = condition.DelayBeforeRetry; } // Perform an extra check in the delay interval. Should prevent from accidentally ending up with the // value of -1 that will block a thread indefinitely. In addition, any other negative numbers will // cause an ArgumentOutOfRangeException fault that will be thrown by Thread.Sleep. if (delay.TotalMilliseconds < 0) { delay = TimeSpan.Zero; } this.OnRetrying(retryCount, lastError, delay); if (retryCount > 1 || !this.RetryStrategy.FastFirstRetry) { PlatformTask.Delay(delay).Wait(); } } }
private Task <TResult> ExecuteAsyncContinueWith(Task <TResult> runningTask) { if (!runningTask.IsFaulted || this._cancellationToken.IsCancellationRequested) { return(runningTask); } TimeSpan delay = TimeSpan.Zero; Exception lastError = runningTask.Exception.InnerException; if (!(this._isTransient(lastError))) { // if not transient, return the faulted running task. return(runningTask); } RetryCondition condition = this._shouldRetryHandler(this._retryCount++, lastError); if (!condition.RetryAllowed) { return(runningTask); } delay = condition.DelayBeforeRetry; // Perform an extra check in the delay interval. if (delay < TimeSpan.Zero) { delay = TimeSpan.Zero; } this._onRetrying(this._retryCount, lastError, delay); this._previousTask = runningTask; if (delay > TimeSpan.Zero && (this._retryCount > 1 || !this._fastFirstRetry)) { return(PlatformTask.Delay(delay) .ContinueWith <Task <TResult> >(this.ExecuteAsyncImpl, CancellationToken.None, TaskContinuationOptions.ExecuteSynchronously, TaskScheduler.Default) .Unwrap()); } return(this.ExecuteAsyncImpl(null)); }