在foreach循环中使用asyc await是不正确的吗?我收到WebException,请求被取消了。
以下是我正在处理的代码的概述。如果不清楚,请告诉我。
using (var client = new HttpClient())
{
client.BaseAddress = new Uri("https://xxx.xxx.com/");
client.DefaultRequestHeaders.Accept.Clear();
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
try
{
var response = await client.PostAsJsonAsync("customers/xxxx/xxx/documents", requestMessage);
response.EnsureSuccessStatusCode();
var returnValue = response.Content.ReadAsAsync<ResponseMessage>();
var hasDocuments = returnValue.Result.SearchResults.Any();
if (hasDocuments)
{
// HTTP GET
client.DefaultRequestHeaders.Accept.Clear();
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("*/*"));
returnValue.Result.SearchResults.ForEach(async d =>
{
response = await client.GetAsync(d.Self + ".pdf");
});
}
}
catch (Exception ex)
{
throw;
}
}
答案 0 :(得分:7)
您没有在foreach
循环中使用async / await,而是使用as {/等待List<T>.ForEach(Action<T>)
。由于ForEach
仅接受Action<T>
(void返回类型),因此ForEach(async d => { ... }
作为async void
函数进行处理,因为这是将Action<T>
传递为foreach
的唯一方式{1}}。这使得ForEach不会等到上一个项目完成后再转移到下一个项目,这就是导致错误的原因。
使用普通List<T>.ForEach
代替 if (hasDocuments)
{
// HTTP GET
client.DefaultRequestHeaders.Accept.Clear();
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("*/*"));
foreach (var d in returnValue.Result.SearchResults)
{
response = await client.GetAsync(d.Self + ".pdf");
};
}
方法,它应该可以正常工作。
async d => ...
您被允许使用Func<T,Task>
的唯一时间是您传入的函数接收IdInstanceTag int,
APPROVED_TIME timestamp,
ModifiedTime date,
DATE_TO date,
DEFINITION XML,
ID int,
CreatedBy varchar(100),
ModifiedBy varchar(100)
时的情况(请参阅Task.Run
)。