问题描述
我创建一个Tasks列表,并使用Task.WhenAll()执行它们。如果http请求返回错误状态,我想重试该呼叫。
我在此行上遇到错误:ExecuteAsync(() => func()));
无法将类型'System.Threading.Tasks.Task'隐式转换为'System.Threading.Tasks.Task
'
我知道错误的含义,但是需要帮助的部分是使用并行http调用并检查响应状态的Polly的总体实现。
代码:
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);
}
解决方法
忽略任何其他问题(概念性或其他问题)
您使用了错误的通用参数HttpWebResponse
,它应该是HttpResponseMessage
,因为SendAsync
会返回
var policy = Policy
.Handle<HttpRequestException>()
.OrResult<HttpResponseMessage>(a => a.StatusCode != HttpStatusCode.OK)
...
此外,您似乎希望将 policy 应用于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
实现中,这反过来又可以解决请求