【问题标题】:If every async has an await and every await is applied to an async, then where and how does this end?如果每个 async 都有一个 await 并且每个 await 都应用于一个 async,那么这在哪里以及如何结束?
【发布时间】:2017-03-17 09:07:50
【问题描述】:

我刚刚被介绍到这个概念,如果答案是微不足道的,请道歉。

我知道async 只是一个标志,表示方法内部有一个await,并且在异步方法执行其工作时控制将返回给调用者。我的理解是,假设调用堆栈中的某个地方没有等待异步方法,至少不是立即等待(即在执行异步方法时完成了一些其他工作),这很有用。

但是,await 似乎只适用于 async 方法,而这些方法又必须有 awaits 内部。这会产生无休止的调用链。它必须在某个地方结束,等待被应用于非异步方法。但是在哪里?

【问题讨论】:

  • 您不能等待非异步方法,但是您可以通过访问任务的 Result 属性等待异步方法完成它的工作。你可以用它来“切断”异步链,或者你可以让你的整个链异步。
  • @TamásSzabó - 是的,你可以。您可以await 任何返回 awaitable 对象的方法。 Task 恰好是最常见的可等待对象。但即使在那里,也不需要Task 返回方法为async。尽管它看起来是方法签名的一部分,但实际上它完全是您正在调用的方法的实现细节。
  • 猜我错了。感谢您清除它!

标签: c# .net asynchronous async-await


【解决方案1】:

但是,await 似乎只适用于异步方法,而这些方法内部必须有 await。

从技术上讲,await 不适用于方法。发生的情况是调用该方法并返回一些内容(例如,Task),然后将await 应用于该任务

所以,误解就在这里:await 应用于可等待对象(例如任务),而不是方法。

它必须在某个地方结束,等待被应用于非异步方法。

是的。任何方法都可以返回Task(或任何可等待的),无论它是否为async。一个方法可以使用async来构造它的任务(大多数我们写的方法都是这样做的),但它也可以直接构建一个。通常,低级异步方法使用TaskFactory.FromAsyncTaskCompletionSource<T> 来创建它们返回的任务。

【讨论】:

    【解决方案2】:

    它最终会出现在您正在使用且您不想阻止的最高层上。假设您有一个 Winforms 应用程序。这里的所有方法都会在某些情况下结束,这将是你的异步链的结束。

    例如:

    private async Task DoSomethingAsync()
    {
       await DbClass.GetSomeItemsFromDbAsync();
    }
    
    public partial class MyForm : Form
    {
       private async void btButton_Click(object sender, EventArgs e)
       {
          await DoSomethingAsync();
       }
    }
    

    如果您可以在示例中看到,我们有一个异步方法。此方法在 Button 的 Click-Event 中调用。所以事件监听器被标记为异步,但不能从其他任何地方调用。在这里,您离开您的链并到达终点。表单不会阻塞,这就是我们想要实现的目标。

    如果您认为在 GUI 上所有方法都将在事件中结束,因为整个程序是事件驱动的。在控制台应用程序中,端点将是主方法。您无需将返回类型从 void 更改为 Task,这将停止您的异步链,因为无法等待 void。

    我希望这能帮助你理解这个链条。

    【讨论】:

    • 在 Windows 窗体中使用async void 是否正常?
    • @mukh1n 在事件监听器上使用它:是的,因为这是您的端点。应该避免在“正常”方法中使用它,因为以后不能等待。
    • 我实际上是在询问最低级别(参见斯蒂芬的回答)。但你的观点也是一个好点:高层的某个人必须不await它,至少不是立即,整个事情才有意义。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-09-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-03-27
    • 2012-08-20
    相关资源
    最近更新 更多