2013-11-27 81 views
0

因此,众所周知,像asp.NET,WPF和WinRT这样的框架为您管理一个或多个线程。在asp.net中,框架汇集了一组线程,它们接收来自队列的请求并处理它们。在WPF中,框架为您管理UI线程,该线程从消息泵获取消息。重用等待线程

这可以通过简单的生产者/消费者方法来实现,其中消费线程执行while(true)循环,从队列中获取消息并使用消息处理程序(用户的代码)执行它们。够简单。您可以在这里找到一个基本的实现:https://stackoverflow.com/a/5828863/857807

通过引入异步电动机/等待语义,你可以委托CPU/IO密集型工作,其他线程,并离开(例如)UI线程响应。这意味着UI线程将继续从泵中获取消息。

我的问题是:从上述基本实现开始,消费者如何实现这一点?您如何知道消息处理程序正在异步等待另一个线程完成,并因此从队列中取出另一条消息?我相信我在这里错过了一些大事。

+0

你问的WPF/etc UI线程是如何做到这一点的,或者你将如何在特定的线程上自己做? –

+0

我确信框架的实际实现对我来说有点矫枉过正,我只想知道它的要点。我没有试图自己实现它,但我想知道如果我想要,我会怎么做,出于好奇。 – dcastro

回答

3

关键是,当一个async方法在await中产生时,它实际上返回给它的调用者。所以,从主循环的角度来看,该方法已经完成。

稍后,等待操作完成后,它会将async方法的其余部分安排到捕获的上下文中。在你提到的情况下(ASP.NET/WPF/WinRT),上下文是SynchronizationContext。在UI框架(WPF/WinRT/WinForms/etc)中,SynchronizationContext与消息队列绑定。

所以,如果你想要一个async兼容的“主循环”,你需要实现一个自定义的SynchronizationContext,它允许代表回到主循环。

欲了解更多信息:

+0

很好的解释,谢谢!我完全忘了消息处理程序通常是一个“异步无效”的方法!当然,这意味着该方法在返回第一个“await”关键字时会返回,从而使消费者继续阅读下一条消息。现在这一切似乎都很明显*。 * – dcastro

+3

@dcastro它会这样做*不管它是否为void或非void。也就是说,除非*需要*来作为事件的处理程序,否则几乎不会有'async void'方法。 – Servy

+0

另外,很棒的链接,我会仔细看看你的图书馆。 – dcastro