C# 在异步MVC web应用程序中寻找关于Task.WhenAll和wait的澄清
我一直在研究如何将异步方法合并到我的MVC控制器中,特别是利用并行执行的潜力 我觉得特别有用。不过,有一个概念我希望澄清一下。上面我链接的文章使用以下代码并行执行一系列I/O绑定方法:C# 在异步MVC web应用程序中寻找关于Task.WhenAll和wait的澄清,c#,asp.net,asp.net-mvc,asynchronous,C#,Asp.net,Asp.net Mvc,Asynchronous,我一直在研究如何将异步方法合并到我的MVC控制器中,特别是利用并行执行的潜力 我觉得特别有用。不过,有一个概念我希望澄清一下。上面我链接的文章使用以下代码并行执行一系列I/O绑定方法: var widgetTask = widgetService.GetWidgetsAsync(); var prodTask = prodService.GetProductsAsync(); var gizmoTask = gizmoService.GetGizmosAsync(); await Task.W
var widgetTask = widgetService.GetWidgetsAsync();
var prodTask = prodService.GetProductsAsync();
var gizmoTask = gizmoService.GetGizmosAsync();
await Task.WhenAll(widgetTask, prodTask, gizmoTask);
var pwgVM = new ProdGizWidgetVM(
widgetTask.Result,
prodTask.Result,
gizmoTask.Result
);
我想知道的是,这与以下代码有何不同:
var widgetTask = widgetService.GetWidgetsAsync();
var prodTask = prodService.GetProductsAsync();
var gizmoTask = gizmoService.GetGizmosAsync();
var pwgVM = new ProdGizWidgetVM(
await widgetTask,
await prodTask,
await gizmoTask
);
据我所知,这两个代码块是等效的。对吗?如果没有,如果有人能解释差异,并建议我的情况下哪个更好,那就太好了。1将并行执行所有3项任务,但不一定按顺序执行。
Task.whalll
完成时,内部的所有任务都已完成widgetTask
将执行到它的第一个等待,然后在异步等待io绑定工作时,prodTask
将执行到它的第一个等待,而在仍然等待前两个任务完成时,GizmotTask
将执行到它的第一个等待。然后,在所有3个并行完成io绑定工作后,它们将运行到完成。在此之后,任务。whalll
也将报告完成情况
2将以给定顺序并行执行所有3项任务
widgetask
将启动,然后prodTask
将启动,然后gizmoTask
。您开始等待widgetTask
。完成后,它将返回并运行此任务中的非io绑定代码。完成后,将等待prodTask
。由于它的io绑定工作是异步的,它可能已经完成了,所以这将非常快。io绑定工作完成后,将调用prodTask
中的wait之后编码。同样适用于gizmoTask
因此,只要您不关心任务内部等待后代码的执行顺序,通常您需要版本1而不是版本2。1将并行执行所有3个任务,但不一定按顺序执行。
Task.whalll
完成时,内部的所有任务都已完成widgetTask
将执行到它的第一个等待,然后在异步等待io绑定工作时,prodTask
将执行到它的第一个等待,而在仍然等待前两个任务完成时,GizmotTask
将执行到它的第一个等待。然后,在所有3个并行完成io绑定工作后,它们将运行到完成。在此之后,任务。whalll
也将报告完成情况
2将以给定顺序并行执行所有3项任务
widgetask
将启动,然后prodTask
将启动,然后gizmoTask
。您开始等待widgetTask
。完成后,它将返回并运行此任务中的非io绑定代码。完成后,将等待prodTask
。由于它的io绑定工作是异步的,它可能已经完成了,所以这将非常快。io绑定工作完成后,将调用prodTask
中的wait之后编码。同样适用于gizmoTask
因此,只要您不关心任务中等待后的代码执行顺序,通常您需要的是版本1而不是版本2。第一个代码片段等待所有任务完成。第二种方法是按顺序等待它们,这不是最容易维护的代码。想象一下,例如在所有任务完成后尝试添加一个断点,以便检查其结果。1是琐碎的,2是不可能的。对了,我明白你关于调试的观点。这是我没有考虑的一个重要问题。但就我的理解而言,我说在#2中,这些方法仍然是并行执行的,对吗?在这种情况下,按顺序等待结果并不重要,因为我只能在所有操作完成后继续操作。
wait
不会影响执行。当您调用异步方法时,任务开始执行<代码>等待仅影响异步等待。仅从这个意义上讲,这两个片段是等效的。但这可能仍然很重要,因为编译器必须为等待生成一个三步状态机,而不是一步状态机。编译器可能足够聪明,可以优化第二个代码段,并将其替换为wait Task。虽然所有的,但我怀疑第一个代码段是否会等待所有任务完成。第二种方法是按顺序等待它们,这不是最容易维护的代码。想象一下,例如在所有任务完成后尝试添加一个断点,以便检查其结果。1是琐碎的,2是不可能的。对了,我明白你关于调试的观点。这是我没有考虑的一个重要问题。但就我的理解而言,我说在#2中,这些方法仍然是并行执行的,对吗?在这种情况下,按顺序等待结果并不重要,因为我只能在所有操作完成后继续操作。wait
不会影响执行。当您调用异步方法时,任务开始执行<代码>等待
仅影响异步等待。仅从这个意义上讲,这两个片段是等效的。但这可能仍然很重要,因为编译器必须为等待生成一个三步状态机,而不是一步状态机。编译器可能足够聪明,可以优化第二个代码段,并将其替换为等待任务。在任务中等待全部3个。等待全部或单独等待不会改变这一点。现在,如果在调用GetWidgetsAsync