如何在Polly的retryPolicy.Execute()中获取重试迭代次数以处理请求重试错误?
在Polly重试策略中获取迭代次数并重新创建HttpRequestMessage
你说得没错,这个错误的根源就是HttpRequestMessage本身是不可重复发送的——第一次发送后它的内部状态会被修改,所以重试时必须重新创建实例。好在Polly完全支持在重试流程中获取当前的迭代次数,而且我们可以结合这个特性优雅地解决问题。
核心思路:每次重试都重新创建请求
最关键的一点是:把创建HttpRequestMessage的逻辑放到Execute(或ExecuteAsync)的委托内部,这样每次执行(包括重试)都会生成一个全新的请求实例,从根源避免重复发送的问题。同时,我们可以轻松获取当前的重试次数。
方法1:在重试回调中获取重试次数
创建重试策略时,通过OnRetry回调可以直接拿到当前的重试次数,适合记录日志或做重试相关的通知:
using Polly; using Polly.Retry; using System.Net.Http; namespace RetryLogic { public class HttpFactory { private static readonly HttpClient _httpClient = new HttpClient(); // 定义重试策略:最多重试3次,捕获请求异常或非成功响应 private static readonly RetryPolicy _retryPolicy = Policy .Handle<HttpRequestException>() .OrResult<HttpResponseMessage>(r => !r.IsSuccessStatusCode) .Retry(3, (exception, retryCount, context) => { // 这里的retryCount就是当前的重试次数(第一次重试是1,第二次是2) Console.WriteLine($"触发重试,当前是第 {retryCount} 次尝试"); }); public HttpResponseMessage SendGetRequest(string url) { return _retryPolicy.Execute(_ => { // 每次执行都创建新的HttpRequestMessage var request = new HttpRequestMessage(HttpMethod.Get, url); return _httpClient.SendAsync(request).Result; }); } } }
方法2:在请求创建时直接使用重试次数
如果需要在请求本身中用到重试次数(比如添加自定义请求头标记重试),可以通过Polly的Context对象获取当前执行次数:
public HttpResponseMessage SendRequestWithRetryHeader(string url) { return _retryPolicy.Execute(context => { // context.Count记录了当前执行次数:初始执行是0,第一次重试是1,以此类推 var currentRetryCount = context.Count; var request = new HttpRequestMessage(HttpMethod.Get, url); request.Headers.Add("X-Retry-Attempt", currentRetryCount.ToString()); return _httpClient.SendAsync(request).Result; }, new Context()); }
额外注意事项
- 绝对不要在
Execute委托外部创建HttpRequestMessage然后复用,这正是触发你遇到的错误的原因。 - 如果使用异步请求,对应改用
RetryAsync和ExecuteAsync方法,逻辑完全一致,只需调整为异步写法。 - 对于指数退避等更复杂的重试策略(比如
WaitAndRetry),同样可以在回调中获取retryCount参数。
内容的提问来源于stack exchange,提问作者SaiGiridhar
相关产品推荐
相关产品推荐

