×

Loading...

我是学C++的,所以思维总是从硬件线程的角度出发。经过仔细阅读若干篇MSDN文章,终于明白了async/await的工作原理(从Win32和硬件线程的角度):

本文发表在 rolia.net 枫下论坛如果一个.net函数有async关键字,编译器会自动为其生成一个数据结构,这个数据结构包含函数内部变量以及引用的局部变量等信息;同时编译器为这个函数生成另外一个或者两个更为复杂的函数,新生成的函数利用之前提到的数据结构来记录这个async函数执行到了那里,在等待什么,以及相关的数据(例如局部变量的值)。新生成的函数和数据结构被称为“状态机”,这个状态机允许一个函数被分成若干次运行,在每次运行时利用状态机的数据来从上次运行停止的地方接着运行,一般是await的下一条指令。

当一个async函数里执行await时,.net会在状态机里记录下当先执行到了那里,当前局部变量的值,在另外的工作线程中开始异步操作,然后将当前线程的控制权返回到调用者。当工作线程的异步操作完成时,.net会在“某个”synchronization context里post一个消息,当运行这个synchronization context的线程中的消息循环处理这个消息时,它会找到相应的状态机,调用相关的函数回复这个状态机的运行。如果async函数里有多个await时,.net会重复这个步骤。

前面提到“某个”synchronization context,如果调用await时的线程是UI线程,那么.net默认在UI线程恢复执行状态机;否则有可能在完成异步操作的线程中恢复执行虚拟机。

简单的说,.net编译器会自动产生一些数据和额外的代码构成一个能够让函数分多步完成的虚拟机,以及相应的调用虚拟机的机制,这就是asnyc/await的背后实现原理,编译器承担了几乎全部的背后工作。更多精彩文章及讨论,请光临枫下论坛 rolia.net
Sign in and Reply Report