最初的方法是低效的foreach
循环,等待每个作业(job)(这是一个I/O绑定的网络调用):
foreach (var job in Jobs)
{
try
{
await DoJobAsync(job); //Pass job to external vendor API
job.Succeeded = true;
}
catch (Exception)
{
//do nothing, let loop continue
}
}
现在为了提高性能,我希望使用Task.WhenAll
以非阻塞方式处理所有作业(job).
但是,如果DoJobAsync
任务没有引发异常,我们需要确保每个job
对象只有Succeeded
属性设置为true
.
如果我们这样做:
await Task.WhenAll(Jobs.Select(j =>
{
var task = DoJobAsync(j);
j.Succeeded = true;
return task;
}));
我的理解是,如果任何作业(job)任务最终抛出异常,该属性仍将切换为true
,因 for each 单独的任务在创建时都不会等待,从而使代码流直接经过它.
我知道我可以捕获Task.WhenAll
返回的Task
,以访问抛出的所有异常的列表,但我无法找到使用它们追溯到抛出异常的job
的方法.
我如何解决这个问题?