【问题标题】:When I "await" an "async" method does it become synchronous?当我“等待”一个“异步”方法时,它会变得同步吗?
【发布时间】:2015-12-05 14:00:10
【问题描述】:

所以这里是场景:

static async void Main(string[] args) 
{
    await AnAsyncMethod();
}

private static async task<bool> AnAsyncMethod()
{
    var x = await someAsyncMethod();
    var y = await someOtherAsyncMethod();

    return x == y;
}

“someAsyncMethod”和“someOtherAsyncMethod”是因为我们正在使用等待而同步运行,还是它们都按照执行顺序异步运行?

更新

鉴于下面的答案表明等待的异步方法将按顺序运行,如果我们只是要停止执行并等待这些方法的返回值,那么首先使这些方法调用异步的目的是什么?过去我看到原生应用程序使用 await/async 作为释放 UI 线程的一种方式,但是还有其他原因可以说明这种设计是可取的吗?

【问题讨论】:

  • 小旁注Main 不能使用await,因为它本身没有标记为async
  • 我的理解是 someAsyncMethod 将在 someOtherAsyncMethod 开始之前完全完成。
  • @Biscuits 甚至不是这样 - await 与方法(或它们的任务)的执行方式无关;它只是处理任务完成时发生的事情。如果我想通过添加一个简单的扩展方法,我可以等待一个可枚举的。它与线程无关(实际上与任务无关)。
  • @dcastro 感谢您的深入跟进!
  • what would be the purpose of making those method calls asynchronous in the first place 我希望更多人问这个问题...也许你会喜欢我关于何时使用异步 IO 以及为什么使用的标准帖子:stackoverflow.com/a/25087273/122718 为什么 EF 6 教程使用异步调用? stackoverflow.com/a/12796711/122718我们应该切换到默认使用异步 I/O 吗?

标签: c# asynchronous async-await


【解决方案1】:

它们是异步运行的,但顺序运行。在someAsyncMethod 完成之前,someOtherAsyncMethod 不会被调用。

如果您想并行运行它们,您有多种选择

var taskA = MethodA();
var taskB = MethodB();

var a = await taskA;
var b = await taskB;

// or

var results = await Task.WhenAll(MethodA(), MethodB());

后续问题:

过去我曾看到原生应用程序使用 await/async 作为释放 UI 线程的一种方式,但还有其他原因可以说明这种设计是可取的吗?

在 ASP.NET 应用程序中,您将希望使用它来允许当前线程返回线程池并服务其他传入请求,同时 MethodA/MethodB 正在运行 - 如果这些方法正在运行真正的异步 I/O。这基本上是您在 ASP.NET 应用程序中执行此操作的唯一原因。

您可能还想阅读 Stephen Cleary 的文章:

【讨论】:

  • 请注意,您不能在同一上下文中将 Task.WhenAll 与多个 EF 调用一起使用。那个肯定以前咬过我。
  • 不仅在 ASP.NET 中 - 在任何多用户服务器应用程序中,您都将从保持低线程数中受益。每个线程都意味着不可忽略的内存和 CPU 使用率 - 如果您有 4000 个线程,那么仅在默认线程堆栈上就会丢失 4 GiB 的内存(希望至少是未提交的)。而且由于您的线程数与您拥有的 CPU 内核数一样多,因此,这完全是不必要的浪费。在 32 位应用程序中尤其如此,其中甚至 虚拟 内存的数量也是有限的。
  • @Luaan 感谢补充,非常有用!
  • @Biscuits 选项 1 将启动这两个任务,然后 然后 等待它们。不管你是等a 然后b,还是先等b 然后a。重要的是您在等待 either 之前启动 both
  • @Biscuits 混淆是可以理解的,因为这些表达式不是referentially transparent。也就是说,将taskA 替换为MethodA() 会改变程序的含义
猜你喜欢
  • 2016-02-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-12-28
  • 1970-01-01
  • 1970-01-01
  • 2015-06-09
  • 2023-01-26
相关资源
最近更新 更多