【发布时间】:2023-04-19 22:51:02
【问题描述】:
我有一个项目列表,对于每个项目我需要执行几个异步 API 请求并处理响应,我已经看到了几个实现,它们在执行时间方面都很相似,但我想知道区别他们之间。
方法 1
Parallel.ForEach(items, new ParallelOptions { MaxDegreeOfParallelism = 10 }, item =>
{
var response = item.propertyOne.GetAsync().GetAwaiter().GetResult();
//process it
var response = item.propertyTwo.GetAsync().GetAwaiter().GetResult();
//process it
var response = item.propertyThree.GetAsync().GetAwaiter().GetResult();
//process it
});
方法 2
Parallel.ForEach(items, new ParallelOptions { MaxDegreeOfParallelism = 10 }, item =>
{
Task.Run(async () =>
{
var response = await item.propertyOne.GetAsync();
}).GetAwaiter().GetResult();
//process it
Task.Run(async () =>
{
var response = await item.propertyTwo.GetAsync();
}).GetAwaiter().GetResult();
//process it
Task.Run(async () =>
{
var response = await item.propertyThreee.GetAsync();
}).GetAwaiter().GetResult();
//process it
});
方法 3 假设应用了一些边界机制,以免系统充满任务
List<Task> tasksToAwait = new List<Task>();
foreach (var item in items)
{
tasksToAwait.Add(Task.Run(async () =>
{
var response = await item.propertyOne.GetAsync();
//process it
var response = await item.propertyTwo.GetAsync();
//process it
var response = await item.propertyThree.GetAsync();
//process it
}));
}
await Task.WhenAll(taskToAwait);
注意事项:
- 我使用 GetAwaiter().GetResult() 而不是 Wait(),因为它不会吞下异常。
- 必须以某种方式等待请求才能处理响应。
- 这是作为后台任务执行的,所以我不介意阻塞调用线程。
- 第三种方法略快于其他两种方法,第二种方法略快于第一种方法。
- 我无法控制通过 GetAsync() 调用的异步 API。
推荐其中哪一项,如果没有,您有什么建议?另外,它们有什么不同,为什么会有执行时间差异?
【问题讨论】:
-
好问题,我通常只是将任务存储在列表中,然后执行WhenAll
标签: c# asp.net-core task parallel.foreach