如何实现基于HTML响应内容的重试策略?

时间:2019-02-15 18:23:31

标签: c# polly

我正在使用WebClient使用System.Net.WebClient类从网站读取一些html内容。有时该网站给我200条带有标题标签的响应,表明通话限制已超出,我应在几秒钟后重试。我正在寻找的是一些重试策略,该策略读取该标题标签并检查该调用限制是否超出错误。如果存在该错误,则应重试。这是调用该网站的示例代码

        using (var wc = new GZipWebClient())
        {
            // this html sometimes contain <title> with error message
            html = await wc.DownloadStringTaskAsync(url);
        }

如果有人可以提供有关如何在这种情况下使用Polly实现重试逻辑的示例代码,我将不胜感激。

2 个答案:

答案 0 :(得分:0)

照常使用Polly,并在html中出现错误时引发自定义异常。下面的简单示例。

    private async Task DownloadAsync()
    {
       using (var wc = new GZipWebClient())
       {
          // this html sometimes contain <title> with error message
          html = await wc.DownloadStringTaskAsync(url);

          if (html.Contains("My Error Message")) 
          {
              // Log Error
              throw new MyDownloadFailedException(html);
          }
      }
   }

   // In your calling method
   var p = Policy
            .Handle<MyDownloadFailedException>()
            .RetryForever(exception =>  
            {
                // log.Warning("Failed, retrying....");
            });

   p.ExecuteAsync(async() => await DownloadAsync());

答案 1 :(得分:0)

Polly策略可以handle results natively以及例外。无需使通过策略执行的代码抛出异常来触发重试。

var retryPolicy = Policy
    .HandleResult<string>(s => s.Contains("whatever text triggers retry")) // or whatever more complicated predicate you want
    .Retry...Async(...); // whatever flavour of retry overload you want

private async Task DownloadAsync()
{
   using (var wc = new GZipWebClient())
   {
      // this html sometimes contain <title> with error message
      html = await retryPolicy.ExecuteAsync(() => wc.DownloadStringTaskAsync(url));
   }
}

单个策略实例既可以处理异常也可以处理结果,因此异常处理也可以合并到上面的策略中。


如果调用的API的响应中还包含有关重试前要等待多长时间(“ RetryAfter”)的信息,则Polly还提供了specific patterns allowing you to construct a policy which automatically waits for exactly the retry-after time specified in the response