在多个等待任务上使用await
与等待完成所有任务时有什么区别。我的理解是方案2在性能方面更好,因为asyncTask1和asyncTask2都是并行执行的。
方案1:
async Task Task()
{
await asyncTask1();
await asyncTask2();
}
方案2:
async Task Task()
{
t1 = asyncTask1();
t2 = asyncTask2();
await Task.WhenAll(createWorkflowtask, getTaskWorkflowTask);
}
答案 0 :(得分:6)
在方案1中,任务按顺序运行(asyncTask1必须在asyncTask2启动之前完成),而在方案2中,两个任务可以并行运行。
答案 1 :(得分:3)
在第一个场景中,你启动一个任务,然后等到完成,然后转到第二个,然后等到完成,然后退出方法。
在第二个场景中,您并行启动两个任务,然后等到调用Task.WhenAll
时完成tgey
答案 2 :(得分:3)
您写道:" ...因为asyncTask1和asyncTask2都是并行执行的。"
不,不是!
补充:下面我写道,async-await中的所有内容都由一个线程执行。 Schneider正确地评论说,在async-await中可以涉及多个线程。见最后的补充。
一篇帮助我理解async-await如何工作的文章是this interview with Eric-Lippert谁将async / await与做饭的晚餐进行了比较。 (在某处中途,搜索async-await)。
Eric Lippert解释说,如果一个厨师开始做某事并在一段时间后发现他没有别的事情可以等待一个过程完成,那么这位厨师四处寻找他是否可以做其他事情而不是等待。 / p>使用async / await时,仍然涉及一个线程。这个线程一次只能做一件事。当线程忙于执行Task1时,它无法执行Task2。只有在Task1中找到await时,它才会开始执行Task2中的语句。在您的方案2中,任务不会并行执行。
然而情景之间存在差异。在方案1中,task1的第一个语句将在task1完全完成之前不执行。一旦task1遇到等待,场景2将开始执行task2的第一个语句。
如果你真的希望task2在task1做某事时做某事,你必须在一个单独的线程中开始做task2。在您的方案中执行此操作的简单方法是:
var task1 = Task.Run( () => asyncTask1())
// this statement is executed while task1 begins executing on a different thread.
// hence this thread is free to do other things, like performing statements
// from task2:
var task2 = asyncTask();
// the following statement will only be executed if task2 encounters an await
DoSomethingElse();
// when we need results from both task1 and task2:
await Task.WhenAll(new Task[] {task1, task2});
通常,如果您需要此任务的结果,最好只等待任务完成。只要你可以做其他的事情,做其他的事情,一旦其他任务开始等待,它们将被执行,直到你开始等待,在这种情况下你的来电者将开始做事直到他等待等等。
这种方法在上面并行处理的优点有很多:
另外:施耐德关于以下几条主题的评论是正确的。
一些测试显示,等待任务中当前线程的线程ID与调用线程的线程ID不同。
对于异步等待的新手,重要的是要理解尽管涉及各种线程,但async-await并不意味着任务是并行执行的。如果你想要并行性,你必须要说任务必须并行运行。
Eric Lippert的厨师似乎实际上是一个厨师团队,他们不断环顾四周,看看他们是否可以帮助其他厨师,而不是等待他们的任务完成。事实上,如果阿尔伯特看到等待并开始做其他事情,伯纳德厨师可能会完成阿尔伯特厨师的任务。
答案 3 :(得分:1)
使用Task.WhenAll
WhenAll
方法来自MSDN
如果任何提供的任务在故障状态下完成,则返回的任务也将在TaskStatus.Faulted状态下完成,其中异常将包含来自每个提供的任务的一组未包装的异常的聚合。
在多种方法上使用await
您可以控制名为
您可以使用不同的返回类型,并在后续步骤中使用该返回类型
一种方法中未处理的异常会破坏其他方法的执行