You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.25 08:04:55