使用 Parallel.Foreach 时我们必须等待所有异步调用吗?
Must we wait for all async calls when using Parallel.Foreach?
假设我们有一个过滤器列表,使用Parallel.ForEach进行异步调用然后使用它们是否可以?我们必须等待所有呼叫结束吗?如果我们有 3 个异步调用和一个 fails/times 输出怎么办?
var results = new ConcurrentBag<Service>();
Parallel.ForEach(filters, async filter =>
{
var result = await serviceClient.GetAllAsync(filter).ConfigureAwait(false);
results.AddRange(result);
});
MyMapper.Map(results);
MyMapper 有一个方法:
Map(IEnumerable<Service> services) {
foreach(Service service in services) {
//do stuff
}
}
我会做一些不同的事情。假设
serviceClient.GetAllAsync(filter)
正在不同的 thread/task 中做某事或对某些 url 提出请求,我认为没有必要使用 Paralle.ForEach。
我要做的是创建一个任务列表并使用 Task.WaitAll 方法调用它们。这样你就可以处理错误任务的任何异常。
此代码段与此类似:
var queryService = filters.Select(x => sClient.GetAllAsync()).ToArray();
try
{
// Wait for all the tasks to finish.
Task.WaitAll(queryService);
}
catch (AggregateException e)
{
//At least one of the Task instances was canceled.
//If a task was canceled, the AggregateException contains an OperationCanceledException in its InnerExceptions collection.
}
Parallel
库被认为可以并行处理数百万个项目。在那里使用 Parallel.ForEach
不会有任何改善。您可以改用 Task.WhenAll。
var tasks = new List<Task>();
foreach(var filter in filters)
{
tasks.Add(serviceClient.GetAllAsync(filter));
}
results.AddRange(await Task.WhenAll(tasks).ConfigureAwait(false));
你可以做一些 LinQ。我没有,所以这个想法更清楚。
使用此代码,您可以获得一定程度的并行性,await
将帮助您处理异常。
假设我们有一个过滤器列表,使用Parallel.ForEach进行异步调用然后使用它们是否可以?我们必须等待所有呼叫结束吗?如果我们有 3 个异步调用和一个 fails/times 输出怎么办?
var results = new ConcurrentBag<Service>();
Parallel.ForEach(filters, async filter =>
{
var result = await serviceClient.GetAllAsync(filter).ConfigureAwait(false);
results.AddRange(result);
});
MyMapper.Map(results);
MyMapper 有一个方法:
Map(IEnumerable<Service> services) {
foreach(Service service in services) {
//do stuff
}
}
我会做一些不同的事情。假设
serviceClient.GetAllAsync(filter)
正在不同的 thread/task 中做某事或对某些 url 提出请求,我认为没有必要使用 Paralle.ForEach。
我要做的是创建一个任务列表并使用 Task.WaitAll 方法调用它们。这样你就可以处理错误任务的任何异常。
此代码段与此类似:
var queryService = filters.Select(x => sClient.GetAllAsync()).ToArray();
try
{
// Wait for all the tasks to finish.
Task.WaitAll(queryService);
}
catch (AggregateException e)
{
//At least one of the Task instances was canceled.
//If a task was canceled, the AggregateException contains an OperationCanceledException in its InnerExceptions collection.
}
Parallel
库被认为可以并行处理数百万个项目。在那里使用 Parallel.ForEach
不会有任何改善。您可以改用 Task.WhenAll。
var tasks = new List<Task>();
foreach(var filter in filters)
{
tasks.Add(serviceClient.GetAllAsync(filter));
}
results.AddRange(await Task.WhenAll(tasks).ConfigureAwait(false));
你可以做一些 LinQ。我没有,所以这个想法更清楚。
使用此代码,您可以获得一定程度的并行性,await
将帮助您处理异常。