我正在尝试使用异步CTP并非常喜欢它。白皮书中确实有一个问题对此做了解释。在其中说:
如果它们不在自己的线程上运行,那么异步行为如何工作?在(例如)UI和“await”关键字创建的Task之间的现有线程上是否有很多上下文切换?
最佳答案
当您调用异步方法时,它最初是同步的。在等待之前,它甚至没有机会异步。
在每个waiting表达式中,在您正在等待的awaitable上调用GetAwaiter()
。然后在等待者上测试IsCompleted
属性。如果任务已经完成,则该方法将保持同步进行。
否则,将在等待者上调用OnCompleted
方法,以向其添加一个延续,然后在任务完成时将其回调。异步方法本身在第一次遇到尚未完成的await表达式时便返回给调用方。
线程的确切性质取决于所涉及的等待者,但是在Task<T>
的异步CTP中,TaskAwaiter
将使用当前的任务调度程序来调度继续。对于WinForms/Silverlight/WPF,这意味着,如果在UI线程上启动异步方法,则该方法将在UI线程上继续。否则(例如,如果您已经在线程池线程上,或者正在通过控制台应用程序使用它),则继续将在线程池线程上运行。当然,您可以根据需要自行更改current task scheduler。
同样,不同的服务员也不必使用TaskScheduler.Current
安排继续。例如,我的协程连续基本上保持了要执行的连续队列,并一直继续下去直到它们执行完为止。我的ComeFrom延续最终变得更加离奇:)
有关异步功能如何在幕后工作的更多信息,请阅读我的Eduasync blog series,它非常深入地研究了它。
希望您总体上喜欢此功能...我认为它非常令人兴奋。