/// <summary> /// Sends an HTTP request to the inner handler to send to the server as an asynchronous operation. /// </summary> /// <param name="request">The HTTP request message to send to the server.</param> /// <param name="cancellationToken">A cancellation token to cancel operation.</param> /// <returns>The task object representing the asynchronous operation.</returns> protected override async Task <HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken) { this.RetryPolicy.Retrying += (sender, args) => Retrying?.Invoke(sender, args); HttpResponseMessage responseMessage = null; try { await this.RetryPolicy.ExecuteAsync(async() => { responseMessage = await base.SendAsync(request, cancellationToken).ConfigureAwait(false); if (!responseMessage.IsSuccessStatusCode) { // dispose the message unless we have stopped retrying this.Retrying += (sender, args) => { if (responseMessage != null) { responseMessage.Dispose(); responseMessage = null; } }; throw new HttpRequestWithStatusException(responseMessage); } return(responseMessage); }, cancellationToken).ConfigureAwait(false); return(responseMessage); } catch { if (responseMessage != null) { return(responseMessage); } else { throw; } } finally { if (Retrying != null) { foreach (EventHandler <RetryingEventArgs> d in Retrying.GetInvocationList()) { Retrying -= d; } } } }
private void ApplyRetryingEvent(object sender, SqlRetryLogicBase retryLogic, TimeSpan intervalTime, List <Exception> exceptions, Exception lastException) { string methodName = MethodBase.GetCurrentMethod().Name; if (Retrying != null) { var retryEventArgs = new SqlRetryingEventArgs(retryLogic.Current, intervalTime, exceptions); SqlClientEventSource.Log.TryTraceEvent("<sc.{0}.{1}|INFO> Running the retrying event.", TypeName, methodName); Retrying?.Invoke(sender, retryEventArgs); if (retryEventArgs.Cancel) { SqlClientEventSource.Log.TryTraceEvent("<sc.{0}.{1}|INFO> Retry attempt cancelled (current retry number = {2}).", TypeName, methodName, retryLogic.Current); throw CreateException(exceptions, retryLogic, true); } } SqlClientEventSource.Log.TryTraceEvent("<sc.{0}.{1}|INFO> Wait '{2}' and run the action for retry number {3}.", TypeName, methodName, intervalTime, retryLogic.Current); }
/// <summary> /// Notifies the subscribers whenever a retry condition is encountered. /// </summary> /// <param name="retryCount">The current retry attempt count.</param> /// <param name="lastError">The exception that caused the retry conditions to occur.</param> /// <param name="delay">The delay that indicates how long the current thread will be suspended before the next iteration is invoked.</param> protected virtual void OnRetrying(int retryCount, Exception lastError, TimeSpan delay) { Retrying?.Invoke(this, new RetryingEventArgs(retryCount, delay, lastError)); }
/// <summary> /// Sends an HTTP request to the inner handler to send to the server as an asynchronous /// operation. Retries request if needed based on Retry Policy. /// </summary> /// <param name="request">The HTTP request message to send to the server.</param> /// <param name="cancellationToken">A cancellation token to cancel operation.</param> /// <returns>Returns System.Threading.Tasks.Task<TResult>. The /// task object representing the asynchronous operation.</returns> protected override async Task <HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken) { SubscribeRetryPolicyRetryingEvent(); HttpResponseMessage responseMessage = null; try { await RetryPolicy.ExecuteAsync(async() => { responseMessage = await base.SendAsync(request, cancellationToken).ConfigureAwait(false); if (!responseMessage.IsSuccessStatusCode) { // dispose the message unless we have stopped retrying this.Retrying += (sender, args) => { if (responseMessage != null) { responseMessage.Dispose(); responseMessage = null; } }; throw new HttpRequestWithStatusException(string.Format( CultureInfo.InvariantCulture, Resources.ResponseStatusCodeError, (int)responseMessage.StatusCode, responseMessage.StatusCode)) { StatusCode = responseMessage.StatusCode }; } return(responseMessage); }, cancellationToken).ConfigureAwait(false); return(responseMessage); } catch (Exception ex) { if (responseMessage != null) { return(responseMessage); } else { throw ex; } } finally { if (Retrying != null) { foreach (EventHandler <RetryingEventArgs> d in Retrying.GetInvocationList()) { Retrying -= d; } } } }