1

DelegateHandler我已经在写入 .NET Standard 2.0 的 dll 中实现了 Polly 在它自己的“重试”HttpClient中。我有 Polly v7.2.3 包。MyHttpClient与 an 分开运行,HttpClientFactory因为在 dll 的短暂生命周期内只有一个实例会存在。

我的问题是:当我的互联网工作时,代码执行得很好。但是,当我断开互联网连接时,它会TaskCanceledException在第一次重试时抛出一个并且不再重试。这是我的代码的相关部分...

在我输入的 HttpClient 的 ctor 中:

this.Client = new System.Net.Http.HttpClient(
new ATCacheDelegatingHandler(
    new RetryPolicyDelegatingHandler(
        new HttpClientHandler()))));

在我的重试委托处理程序中:

this.RetryPolicy =
Policy.Handle<HttpRequestException>()
    .Or<TaskCanceledException>()
    .WaitAndRetryAsync(numRetries,
        retryAttempt => TimeSpan.FromSeconds(Math.Pow(2, retryAttempt-1) * 15));

所以我在这里对 SO 进行了研究,发现了这个非常有希望Dispose的解释和解决方案,建议我调用结果。 HttpClient Polly WaitAndRetry 策略

这是我使用该解决方案的更新代码。调用WaitAndRetryAsync抱怨它无法解析该OnRetry方法,因为它正在寻找“Action<Exception, TimeSpan>”

private void WaitAndRetry(int numRetries)
{
    this.RetryPolicy =
        Policy.Handle<HttpRequestException>()
            .Or<TaskCanceledException>()
            .WaitAndRetryAsync(numRetries,
                retryAttempt => TimeSpan.FromSeconds(Math.Pow(2, retryAttempt-1) * 15)
                , OnRetry); // reference to the method below
}

// unable to match to these parameters from the "WaitAndRetryAsync" call above
private Task OnRetry(DelegateResult<HttpResponseMessage> response, TimeSpan span, int retryCount, Context context)
{
    if (response == null)
        return Task.CompletedTask;

    // this is the "Dispose" call from that SO solution I referenced above
    response.Result?.Dispose();
    return Task.CompletedTask;
}

DelegateResult<HttpResponseMessage>不幸的是,我使用的 Polly 版本不支持参数。所有onRetry支持都期望第一个参数是“异常”。Dispose如果我无法接触到一次性物品,我会在使用该溶液时死在水中。

更新:我希望能够Dispose()从其他 StackOverflow 反馈中调用以影响修复。但我不能,因为该onRetry方法不支持同一组参数(即“响应”对象)。Polly API 似乎发生了变化。如果是这样,那么获得响应访问权限的新方法是Dispose什么?或者有没有其他方法可以解决我遇到的错误?

所以我被困在试图让这个解决方案工作或寻找另一种方法来解决这个异常。我欢迎任何有关如何指定要处理的对象的反馈。也欢迎替代方法。

4

1 回答 1

1

您需要做的就是HttpResponseMessage在声明策略时将 指定为返回类型。

IAsyncPolicy<HttpResponseMessage> retryPolicy = Policy<HttpResponseMessage>
    .Handle<HttpRequestException>()
    .Or<TaskCanceledException>()
    .WaitAndRetryAsync(numRetries,
    retryAttempt => TimeSpan.FromSeconds(Math.Pow(2, retryAttempt - 1) * 15), 
        OnRetry);

所以,而不是Policy.Handle...使用Policy<HttpResponseMessage>.Handle...

于 2022-01-28T16:55:05.357 回答