假设我们有一个过滤器列表,可以使用Parallel.ForEach进行异步调用然后使用它们吗?我们必须等待所有通话结束吗?如果我们有3个异步呼叫而一个失败/超时怎么办?
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
}
}
答案 0 :(得分:2)
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
将帮助您解决异常情况。
答案 1 :(得分:-3)
我会做些不同的事情。假设
serviceClient.GetAllAsync(filter)
在不同的线程/任务中执行某项操作,或者对某个URL进行了请求,我看不到需要Paralle.ForEach用法。
我要做的是创建一个Task列表,并使用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.
}