我有以下情况(或者对异步等待机制的基本误解)。
假设您有一组需要很长时间的 1-20 个 Web 请求调用:findItemsByProduct()
。
您想将其包装在一个异步请求中,这样就能够将所有这些调用抽象为一个异步调用,但如果不使用更多线程,我似乎无法做到这一点。
如果我这样做:
int total = result.paginationOutput.totalPages;
for (int i = 2; i < total + 1; i++)
{
await Task.Factory.StartNew(() =>
{
result = client.findItemsByProduct(i);
});
newList.AddRange(result.searchResult.item);
}
}
return newList;
这里的问题是,这些调用不是一起运行,而是一个接一个地等待。 我希望所有的调用一起运行并收获结果。
作为伪代码,我希望代码像这样运行:
forEach item {
result = item.makeWebRequest();
}
foreach item {
List.addRange(item.harvestResults);
}
我不知道如何编写代码来做到这一点..
最佳答案
理想情况下,您应该添加 findItemsByProductAsync
返回 Task<Item[]>
。这样,您就不必使用 StartNew
创建不必要的任务。或Task.Run
.
那么你的代码可以如下所示:
int total = result.paginationOutput.totalPages;
// Start all downloads; each download is represented by a task.
Task<Item[]>[] tasks = Enumerable.Range(2, total - 1)
.Select(i => client.findItemsByProductAsync(i)).ToArray();
// Wait for all downloads to complete.
Item[][] results = await Task.WhenAll(tasks);
// Flatten the results into a single collection.
return results.SelectMany(x => x).ToArray();
关于c# - 创建同步请求的 .net 异步包装器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17301346/