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

博客讨论了C#中两种异步方法的执行流程,MethodA使用多个await,而MethodB使用Task.WaitAll。尽管两者看似并行,但MethodA实为异步串行,MethodB则会阻塞主线程。作者建议使用Task.WhenAll进行优化,以避免不必要的阻塞并实现真正的并行执行。博客强调理解异步编程的正确方式对于提高性能至关重要。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

咨询区

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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值