简体   繁体   中英

Looking for clarification around Task.WhenAll and await in async MVC web app

I've been investigating how to incorporate asynchronous methods into my MVC controllers, specifically to leverage the potential of parallel execution.

I found this article particularly helpful. However there's one concept I'd appreciate clarification on. The article I linked above uses the following code to execute a series of I/O-bound methods in parallel:

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
   );

What I'd like to know is how this differs from the following code:

var widgetTask = widgetService.GetWidgetsAsync();
var prodTask = prodService.GetProductsAsync();
var gizmoTask = gizmoService.GetGizmosAsync();

var pwgVM = new ProdGizWidgetVM(
   await widgetTask,
   await prodTask,
   await gizmoTask
   );

According to my understanding these two code blocks are equivalent. Is that correct? If not it'd be great if someone could explain the difference and suggest which is preferable in my case.

1 will execute all 3 Tasks in parallel but not necessarily in order

Task.WhenAll completes, when all tasks inside have completed. widgetTask will be executed to its first await, then while waiting asynchronous for the io-bound work, prodTask will be executed to its first await and while still waiting for the first 2 Tasks to complete, gizmoTask will be executed to its first await. Then after all 3 have finished executing the io-bound work in parallel, they will run to completion. After this, Task.WhenAll will also report completion.

2 will execute all 3 Tasks in parallel and in the given order

widgetTask will start, then prodTask will start and then gizmoTask . The you start awaiting widgetTask . When it has completed, it will return and the non io-bound code that is inside this task will run. After it has finished, prodTask will be awaited. As the io-bound work of it happened asynchronous it might already be completed, so this will be quite fast. After the io-bound work completed, to code after the await inside of prodTask will be called. Same for gizmoTask

So normally you want version 1 and not version 2 as long as you do not care about the order in which the code after the await inside your task is executed.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM