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

Polly无法在指定异常触发时重试Http请求问题排查

Polly重试策略未生效,直接抛出连接拒绝异常

问题代码

服务定义

var host = new HostBuilder().ConfigureServices(services =>
{
    services
        .AddHttpClient<Downloader>()
        .AddPolicyHandler((services, request) =>
            HttpPolicyExtensions
            .HandleTransientHttpError()
            .Or<SocketException>()
            .Or<HttpRequestException>()
            .WaitAndRetryAsync(
                new[] { TimeSpan.FromSeconds(1), TimeSpan.FromSeconds(10) },
                onRetry: (outcome, timespan, retryAttempt, context) =>
                {
                    Console.WriteLine($"Delaying {timespan}, retrying {retryAttempt}.");
                }));

    services.AddTransient<Downloader>();

}).Build();

Downloader实现

class Downloader
{
    private HttpClient _client;
    public Downloader(IHttpClientFactory factory)
    {
        _client = factory.CreateClient();
    }

    public Download()
    {
        await _client.GetAsync(new Uri("localhost:8800")); // 无应用监听的端口
    }
}

现象

配置上述代码后,预期触发3次请求尝试(初始1次+2次重试)并打印重试日志,但实际无任何重试日志,直接抛出未处理异常:

未处理异常: System.Net.Http.HttpRequestException: 由于目标计算机积极拒绝,无法连接。(127.0.0.1:8800)
---> System.Net.Sockets.SocketException (10061): 由于目标计算机积极拒绝,无法连接。

解决方法

1. 修正HttpClient注入方式

AddHttpClient<Downloader>()已经为Downloader配置了绑定Polly策略的HttpClient,无需通过IHttpClientFactory手动创建新实例,直接注入HttpClient即可:

class Downloader
{
    private readonly HttpClient _client;
    // 直接注入配置好策略的HttpClient
    public Downloader(HttpClient client)
    {
        _client = client;
    }

    public async Task Download()
    {
        await _client.GetAsync(new Uri("http://localhost:8800"));
    }
}

2. 修复Uri格式

原代码中localhost:8800缺少协议头,会被解析为相对Uri,导致异常处理逻辑失效,添加http://确保是绝对路径。

3. 修正方法签名

原Download方法缺少async修饰符和Task返回值,会导致编译错误且无法触发异步重试策略,必须修正为异步方法。

4. 移除重复服务注册

AddHttpClient<Downloader>()已经自动将Downloader注册为Transient服务,无需再调用services.AddTransient<Downloader>(),移除该行避免冲突。

修正后的服务定义:

var host = new HostBuilder().ConfigureServices(services =>
{
    services
        .AddHttpClient<Downloader>()
        .AddPolicyHandler((services, request) =>
            HttpPolicyExtensions
            .HandleTransientHttpError()
            .Or<SocketException>()
            .Or<HttpRequestException>()
            .WaitAndRetryAsync(
                new[] { TimeSpan.FromSeconds(1), TimeSpan.FromSeconds(10) },
                onRetry: (outcome, timespan, retryAttempt, context) =>
                {
                    Console.WriteLine($"Delaying {timespan}, retrying {retryAttempt}.");
                }));

}).Build();

完成上述修改后,Polly重试策略会正常触发,控制台会打印两次重试日志,总共执行3次请求尝试。

内容的提问来源于stack exchange,提问作者Dr. Strangelove

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.19 03:20:17