NET问答: 多个 await 和 Task.WaitAll 是等价的吗?

Posted dotNET跨平台

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了NET问答: 多个 await 和 Task.WaitAll 是等价的吗?相关的知识,希望对你有一定的参考价值。

咨询区

  • 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 将会并发执行,然后在调用线程上阻塞等待它们执行完成。

回过头来说下你的场景,我觉得两者都不该用,原因有两点:

  1. MethodA 肯定是比 MethodB 要慢。

  2. 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# 中使用异步的套路比较多,弄着弄着很多初学者就搞不清楚了,所以说还是得多学多练多理解。

以上是关于NET问答: 多个 await 和 Task.WaitAll 是等价的吗?的主要内容,如果未能解决你的问题,请参考以下文章

await Promise.all() 和多个 await 之间有啥区别?

.net的 async 和 await

.NET4.5 异步编程 async和await

.NET Web应用中为什么要使用async/await异步编程

net异步编程之await

.Net 4.5 的async 和await 的简单理解使用