咨询区
vidalsasoon:
我有下面两个方法:
MethodA: 使用多个 await 方式
public async Task<IHttpActionResult> MethodA()
{
var customer = new Customer();
customer.Widgets = await _widgetService.GetAllWidgets();
customer.Foos = await _fooService.GetAllFoos();
return Ok(customer);
}
MethodB: 使用 Task.WaitAll
public async Task<IHttpActionResult> MethodB()
{
var customer = new Customer();
var getAllWidgetsTask = _widgetService.GetAllWidgets();
var getAllFoosTask = _fooService.GetAllFos();
Task.WaitAll(new List[] {getAllWidgetsTask, getAllFoosTask});
customer.Widgets = getAllWidgetsTask.Result;
customer.Foos = getAllFoosTask.Result;
return Ok(customer);
}
请问从执行流程上来看,这两个方法都是并行执行的吗?是否有一些理由可以让我使用某一个而不使用另一个,我知道这背后的 编译器
对我隐藏了很多的细节,所以在选择上我还是有点懵。
回答区
i3arnon:
你的 MethodA
并不是同步执行的,它的流程是异步串行,即第二个方法必须等待第一个方法执行结束,你的 MethodB
将会并发执行,然后在调用线程上阻塞等待它们执行完成。
回过头来说下你的场景,我觉得两者都不该用,原因有两点:
MethodA 肯定是比 MethodB 要慢。
MethodB 使用了不必要的阻塞。
言外之意,你可以巧妙的组合它们,比如用:Task.WhenAll
,改造后的代码如下:
public async Task<IHttpActionResult> MethodB()
{
var customer = new Customer();
var getAllWidgetsTask = _widgetService.GetAllWidgets();
var getAllFoosTask = _fooService.GetAllFos();
await Task.WhenAll(getAllWidgetsTask, getAllFoosTask);
customer.Widgets = await getAllWidgetsTask;
customer.Foos = await getAllFoosTask;
return Ok(customer);
}
点评区
这个问题问的挺好的,因为在 C# 中使用异步的套路比较多,弄着弄着很多初学者就搞不清楚了,所以说还是得多学多练多理解。