我很难理解如何使用异步并等待工作。
据我所知,当async方法遇到await表达式时,该方法会立即返回,并且在将来的某个时刻,await表达式将返回,并且该方法将继续执行。
然后,当异步方法包含多个等待表达式时,我不明白的是什么?当执行命中第二个await表达式时,由于该方法在第一个await表达式被命中后已经返回,所以围绕第二个await表达式执行会发生什么?
我目前正在阅读两本关于异步和等待的书,但我的黑暗思想都没有被照亮过!
答案 0 :(得分:5)
据我所知,当async方法遇到await表达式时,该方法会立即返回,并且在将来的某个时刻,await表达式将返回,并且该方法将继续执行。
是的,如果等待尚未完成。
当执行命中第二个await表达式时,由于该方法在第一个await表达式被命中后已经返回,所以围绕第二个await表达式执行会发生什么?
它将控制返回到执行延续的任何内容,这将取决于上下文。在UI线程的WinForms应用程序中,它只是事件循环。在线程池线程中,它只是线程池调度程序。
机会是延续实际上根本不关心的任何调用 - 它只是“在上下文中执行的东西”。它可能会继续执行下一步需要做的事情(或者等到有更多的工作)。
重要的是,到目前为止,第一个调用者具有相应的Task
或Task<T>
,以便他们可以判断整个异步方法何时完成。
答案 1 :(得分:1)
可能有助于回忆一下,对于每个等待编译器遇到的情况,它将重写方法的其余部分作为延续。所以2等待将导致2(嵌套)延续,大致相当(虽然过度简化)到:
FirstAsyncThing().ContinueWith(x => {
SecondAsyncThing().ContinueWith(y => {
// etc.
});
});
正如第一个await立即将控制权返回给方法的调用者,第二个将控制权返回给第一个 continuation 的调用者,这是原始方法的第一部分。