首页 > 解决方案 > Polly 处理响应并检查状态码

问题描述

我创建了一个任务列表并使用 Task.WhenAll() 执行它们。如果 http 请求返回错误状态,我想重试调用。

我在这条线上遇到错误:ExecuteAsync(() => func()));

无法将类型“System.Threading.Tasks.Task”隐式转换为“System.Threading.Tasks.Task<System.Net.HttpWebResponse>”

我知道错误意味着什么,但我需要帮助的部分是 Polly 的整体实现,其中包含并行 http 调用和检查响应状态。

代码:

var tasks = new List<Task<string>>();

var policy = Policy
                .Handle<HttpRequestException>()
                .OrResult<HttpWebResponse>(a => a.StatusCode != HttpStatusCode.OK)
                .WaitAndRetryForeverAsync(i => pauseBetweenFailures);

var urls = new List<string>();

foreach (var mediaItem in UploadedMediaItems)
{
    var mediaRequest = new HttpRequestMessage
    {
        RequestUri = new Uri("****"),
        Method = HttpMethod.Get,
        Headers = {
                { "id-token", id_Token },
                { "access-token", access_Token }
            }
    };

    async Task<string> func()
    {
        var response = await client.SendAsync(mediaRequest);
        return await response.Content.ReadAsStringAsync();
    }
    tasks.Add(policy.ExecuteAsync(() => func()));
}

await Task.WhenAll(tasks);

foreach (var t in tasks)
{
    var postResponse = await t;
    urls.Add(postResponse);
}

标签: c#parallel-processingpolly

解决方案


忽略任何其他问题(概念或其他)

你有错误的泛型参数HttpWebResponse,它应该HttpResponseMessageSendAsync返回的

var policy = Policy
   .Handle<HttpRequestException>()
   .OrResult<HttpResponseMessage>(a => a.StatusCode != HttpStatusCode.OK)
   ...

此外,似乎您希望将策略应用于SendAsync方法,而不是返回的本地方法Task<string>

async Task<string> func()
{
   var response = await policy.ExecuteAsync(() => client.SendAsync(mediaRequest));
   return await response.Content.ReadAsStringAsync();
}
tasks.Add(func());

另请注意,您需要HttpRequestMessage为每次重试重新创建一个新的。它们不能重复使用。

这可能看起来更像这样

Task<HttpResponseMessage> Send()
{
   var mediaRequest = new HttpRequestMessage {... };
   return client.SendAsync(mediaRequest);
}

async Task<string> func()
{
    var response = await policy.ExecuteAsync(Send);
    return await response.Content.ReadAsStringAsync();
}
tasks.Add(func());

但是,说到这一切,您可能希望在IHttpClientFactory通过 注册服务时使用更现代的方法将 Polly 添加到实现中AddPolicyHandler,这反过来会处理请求


推荐阅读