1

Goal:
If you have tried the third time and it is not a success. Then you want to use another method.
I would like to to prevent displaying a error message webpage.

Problem:
is it possible to enter a method that is similiar as catch method in WaitAndRetryAsync?

RetryPolicy<HttpResponseMesssage> httpWaitAndRetryPolicy = Policy
    .HandleResult<HttpResponseMessage>(r => !r.IsSuccessStatusCode)
    .WaitAndRetryAsync
        (3, retryAttempt => TimeSpan.FromSeconds(Math.Pow(2. retryAttempt)/2));

Thank you!

Peter Csala
  • 17,736
  • 16
  • 35
  • 75
HelloWorld1
  • 13,688
  • 28
  • 82
  • 145

2 Answers2

2

You can use ExecuteAsync on your policy and then use ContinueWith to handle final response like this:

 RetryPolicy<HttpResponseMessage>
 .Handle<HttpRequestException>()
 .Or<TaskCanceledException>()
 .WaitAndRetryAsync
     (3, retryAttempt => TimeSpan.FromSeconds(Math.Pow(2, retryAttempt) / 2))
 .ExecuteAsync(() =>
 {
     //do stuff that you want retry

 }).ContinueWith(x =>
 {
     if (x.Exception != null)
     {
         //means exception raised during execute and handle it
     }

     // return your HttpResponseMessage
 }, scheduler: TaskScheduler.Default);

Following @TheodorZoulias's comment the best practice for use ContinueWith is to explicit set TaskScheduler to defualt, because ContinueWith change the scheduler to Current and maybe cause to deadlock.

sa-es-ir
  • 3,722
  • 2
  • 13
  • 31
  • Thank you for your help! It almost working working I have applied a new question with source code. https://stackoverflow.com/questions/66612955/content-from-console-writeline-do-with-polly-do-not-work – HelloWorld1 Mar 13 '21 at 11:32
  • 1
    The `ContinueWith` is a [primitive](https://blog.stephencleary.com/2013/10/continuewith-is-dangerous-too.html) method, and should be used with great care, especially in conjunction with async/await code. You should really pass the `TaskScheduler.Default` explicitly every time you use it. – Theodor Zoulias Mar 16 '21 at 09:36
  • 1
    @TheodorZoulias Thanks for your point, answer updated. – sa-es-ir Mar 16 '21 at 15:26
0

First of all the WaitAndRetryAsync returns an AsyncRetryPolicy<T>, not a RetryPolicy<T>, which means that your posted code does not compile.

In case of polly the definition of a policy and the execution of that policy are separated. So, first you define a policy (or a mixture of policies) and then execute it whenever it is needed.

Definition

AsyncRetryPolicy<HttpResponseMessage> retryInCaseOfNotSuccessResponsePolicy = Policy
    .HandleResult<HttpResponseMessage>(r => !r.IsSuccessStatusCode)
    .WaitAndRetryAsync
        (3, retryAttempt => TimeSpan.FromSeconds(Math.Pow(2.retryAttempt) / 2));

Execution

HttpResponseMessage serviceResponse = null;
try
{
    serviceResponse = await retryInCaseOfNotSuccessResponsePolicy.ExecuteAsync(
        async ct => await httpClient.GetAsync(resourceUri, ct), default);
}
catch (Exception ex)
    when(ex is HttpRequestException || ex is OperationCanceledException)
{
    //TODO: log
}

if (serviceResponse == null)
{
    //TODO: log
}
Peter Csala
  • 17,736
  • 16
  • 35
  • 75