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

Polly的WaitAndRetryAsync如何实现RetryCompleted/OnRetryComplete回调功能

问题1:重试次数耗尽后抛出异常的实现

Polly的重试策略在耗尽所有配置的重试次数后,会直接透传最后一次执行的异常或结果,你可以通过两种方式实现抛出异常的需求:

  • 沿用现有逻辑:你在执行委托中调用了EnsureSuccessStatusCode(),该方法会自动将非成功状态码的响应转换为HttpRequestException抛出,你的策略已经配置了捕获该异常重试,重试耗尽后最后一次的异常会直接向外抛出,被外层catch块捕获后转抛自定义异常即可。
  • 策略层统一处理:通过Fallback策略在重试耗尽时统一抛出异常,无需在业务代码中重复处理状态码判断。

问题2:重试耗尽后的自定义回调实现

Polly没有名为OnRetryComplete的内置配置项,但可以通过Fallback策略与PolicyWrap组合实现该需求,所有重试次数耗尽后会自动触发Fallback的自定义逻辑,支持告警推送、日志记录等自定义操作。

完整改造代码示例

策略定义部分

// 重试策略:重试2次,每次间隔200ms
var retryPolicy = Policy
    .Handle<Exception>()
    .OrResult<HttpResponseMessage>(r => !r.IsSuccessStatusCode)
    .WaitAndRetryAsync(2, 
        _ => TimeSpan.FromMilliseconds(200),
        // 可选配置:每次重试触发的回调,可用于记录重试日志
        onRetryAsync: (outcome, timespan, retryAttempt, context) =>
        {
            logger.LogInformation("第 {Attempt} 次重试,间隔 {Delay}ms", retryAttempt, timespan.TotalMilliseconds);
            return Task.CompletedTask;
        });

// Fallback策略:所有重试耗尽后触发,对应你需要的OnRetryComplete效果
var fallbackPolicy = Policy<HttpResponseMessage>
    .Handle<Exception>()
    .OrResult(r => !r.IsSuccessStatusCode)
    .FallbackAsync(
        fallbackAction: (result, context, cancellationToken) =>
        {
            // 此处填写自定义逻辑:推送告警、记录错误日志等
            logger.LogError("所有重试已耗尽,仍未获取成功响应,最后一次状态:{Status}", 
                result.Exception != null ? "请求异常" : result.Result.StatusCode.ToString());
            // 直接抛出自定义异常
            throw new CustomException("多次重试后请求仍失败");
        });

// 组合策略:Fallback外层包裹重试策略,先执行重试,重试耗尽后进入Fallback逻辑
var policyWrap = Policy.WrapAsync(fallbackPolicy, retryPolicy);

业务执行部分

try
{
    var responseMessage = await policyWrap.ExecuteAsync(async () =>
    {
        string requestJson = JsonSerializer.Serialize(eligRequest, new JsonSerializerOptions
        {
            PropertyNamingPolicy = JsonNamingPolicy.CamelCase
        });
        using var content = new StringContent(requestJson, Encoding.UTF8, "application/json");
        return await httpClient.PostAsync("test/api/ate", content);
    });
    return responseMessage;
}
catch (CustomException ex)
{
    // 外层可按需做额外处理后抛出
    logger.LogError(ex, "请求最终执行失败");
    throw;
}

补充说明

  • WaitAndRetryAsync(2, ...)配置代表额外重试2次,加上第一次原始请求,总共会发起3次请求,如果你需要总共2次请求,将重试次数改为1即可。
  • 如果你不想引入Fallback策略,也可以直接在外层catch块中写入自定义逻辑,重试耗尽后抛出的异常会直接进入catch块,效果等价于重试完成回调。

内容的提问来源于stack exchange,提问作者Sheriff

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.02 02:09:05