我一直在研究如何将异步方法并入我的MVC控制器,特别是利用并行执行的潜力。寻找澄清Task.WhenAll并等待在异步MVC的网络应用程序
我发现this article特别有帮助。不过,我希望澄清一个概念。我上面链接文章使用下面的代码并行执行一系列I/O密集型方法:
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中琐碎,在#2中不可能。 –
对,我明白你的意思。这是我没有考虑过的一个重要问题。但为了完整理解,我是否正确地说在#2中方法仍然是并行执行的?在那种情况下,顺序地等待结果并不重要,因为无论如何,只有一切都完成,我才能继续。 – getsetcode
'await'不影响执行。当您调用异步方法时,任务开始执行。 await只影响异步*等待*。从这个意义上讲,这两个片段是相同的。但它可能仍然很重要,因为编译器必须生成一个3步状态机来等待而不是1步状态机。编译器可能足够聪明,可以*优化*第二个片段,并用'await Task.WhenAll'代替它,但我怀疑它 –