我已经断言我对async / await的理解有几次,经常就我是否正确进行辩论。如果有人能够证实或否认我的理解,并清除任何误解,以便我不传播错误的信息,我真的很感激。
async
/ await
是一种在编写异步代码时避免回调地狱的方法。正在执行异步方法的线程在遇到await
时将返回到线程池,并在等待的操作完成后将执行该操作。
JIT会将异步方法拆分为await
点周围的离散部分,允许在保留方法状态的情况下重新进入方法。在封面下,这涉及某种状态机。
async
/ await
并不意味着任何形式的并发。使用async
/ await
编写的应用程序可以完全是单线程的,同时仍然可以获得所有好处,就像node.js尽管有回调一样。与node.js不同,.NET是多线程的,因此通过async
/ await
,您可以获得非阻塞IO的好处,而不使用回调,同时还有多个执行线程。
async
/ await
释放线程以在等待IO完成时执行其他操作。它还可以与TPL结合使用,在多个线程上执行CPU绑定工作,或者在UI线程之外执行。
为了从非阻塞IO中受益,需要在API之上构建异步方法,实际上利用最终由OS提供的非阻塞IO。
这是我理解中最大的争论点。很多人认为在Task
中使用async
/ await
包装阻止操作会带来性能提升。通过创建一个额外的线程来处理操作,将原始线程返回到线程池,然后在任务完成后恢复原始方法,所有发生的都是不必要的上下文切换,而不是真正释放线程来完成其他工作。虽然这不是对async
/ await
的误用,也不像TPL一样,但这种心态似乎源于对async
/ await
的误解。
答案 0 :(得分:13)
这非常正确。
虽然有几点说明:
ThreadPool
线程。Task
)已经完成,则线程将继续同步执行该方法的其余部分。ThreadPool
线程,但这取决于SyncrhonizationContext
和TaskScheduler
。Task.Delay
异步延迟,或者使用SemaphoreSlim.WaitAsync
之类的异步同步结构。