And*_*Gis 2 .net c# task task-parallel-library async-await
经过几个小时的挣扎,我在我的应用中发现了一个错误.我认为下面的两个函数具有相同的行为,但事实证明它们没有.
任何人都可以告诉我幕后真的发生了什么,以及他们为什么会以不同的方式行事?
public async Task MyFunction1(IEnumerable<Task> tasks){
await Task.WhenAll(tasks);
Console.WriteLine("all done"); // happens AFTER all tasks are finished
}
public async Task MyFunction2(IEnumerable<Task> tasks){
foreach(var task in tasks){
await task;
}
Console.WriteLine("all done"); // happens BEFORE all tasks are finished
}
Run Code Online (Sandbox Code Playgroud)
如果所有任务都成功完成,它们的功能相同.
如果您使用WhenAll并且任何项目失败,则在完成所有项目之后仍然无法完成,并且它将表示AggregatException包装所有任务中的所有错误.
如果await每一个那么它会尽快,因为它击中完成任何失败的项目,它会表现为一个异常一个错误,而不是任何其他人.
两者的不同之处在于,在将任何延续添加到其他项目之前,将在开始时WhenAll实现整个IEnumerable权利.如果IEnumerable代表已存在和已启动任务的集合,那么这是不相关的,但如果迭代可枚举的行为创建和/或启动任务,那么在开始时实现序列将并行运行它们并等待在获取下一个任务之前,每个都会顺序执行它们.下面是IEnumerable你可以传递的,就像我在这里描述的那样:
public static IEnumerable<Task> TaskGeneratorSequence()
{
for(int i = 0; i < 10; i++)
yield return Task.Delay(TimeSpan.FromSeconds(2);
}
Run Code Online (Sandbox Code Playgroud)