使用 Task.WhenAll 但需要跟踪每个单独任务的成功
Using Task.WhenAll but each individual Task's success needs to be tracked
原始方法是等待每个作业的低效 foreach
循环(这是一个 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
以非阻塞方式处理所有作业。
但是,如果 DoJobAsync
任务没有,我们需要确保每个 job
对象只有 Succeeded
属性 设置为 true
抛出异常。
如果我们这样做:
await Task.WhenAll(Jobs.Select(j =>
{
var task = DoJobAsync(j);
j.Succeeded = true;
return task;
}));
我的理解是,如果任何作业任务最终抛出异常,属性 仍会切换到 true
,因为每个单独的任务在创建时都不会等待,从而使代码流动直接过去。
我知道我可以捕获 Task.WhenAll
返回的 Task
以访问抛出的所有异常的列表,但我想不出一种方法来使用它们追溯到引发异常的 job
。
我该如何解决这个问题?
Return 来自方法 DoJobAsync() 的结果 true/false。
这样你可以return直接得到结果。
await Task.WhenAll(Jobs.Select(j =>
{
return DoJobAsync(j);
}));
您可以使用异步委托作为 Select
运算符的 selector
:
await Task.WhenAll(Jobs.Select(async job =>
{
await DoJobAsync(job);
job.Succeeded = true;
}));
这样每个作业都将被投影到一个 Task
,它不是原始的 DoJobAsync(job)
任务,而是一个封装了更新 Succeeded
属性。此 属性 将在 DoJobAsync(job)
任务成功完成后立即更新。
多个 Job
对象可能会并行更新其 Succeeded
属性。这取决于当前线程是否安装了SynchronizationContext
。
原始方法是等待每个作业的低效 foreach
循环(这是一个 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
以非阻塞方式处理所有作业。
但是,如果 DoJobAsync
任务没有,我们需要确保每个 job
对象只有 Succeeded
属性 设置为 true
抛出异常。
如果我们这样做:
await Task.WhenAll(Jobs.Select(j =>
{
var task = DoJobAsync(j);
j.Succeeded = true;
return task;
}));
我的理解是,如果任何作业任务最终抛出异常,属性 仍会切换到 true
,因为每个单独的任务在创建时都不会等待,从而使代码流动直接过去。
我知道我可以捕获 Task.WhenAll
返回的 Task
以访问抛出的所有异常的列表,但我想不出一种方法来使用它们追溯到引发异常的 job
。
我该如何解决这个问题?
Return 来自方法 DoJobAsync() 的结果 true/false。
这样你可以return直接得到结果。
await Task.WhenAll(Jobs.Select(j =>
{
return DoJobAsync(j);
}));
您可以使用异步委托作为 Select
运算符的 selector
:
await Task.WhenAll(Jobs.Select(async job =>
{
await DoJobAsync(job);
job.Succeeded = true;
}));
这样每个作业都将被投影到一个 Task
,它不是原始的 DoJobAsync(job)
任务,而是一个封装了更新 Succeeded
属性。此 属性 将在 DoJobAsync(job)
任务成功完成后立即更新。
多个 Job
对象可能会并行更新其 Succeeded
属性。这取决于当前线程是否安装了SynchronizationContext
。