C#5中新的异步/等待功能如何与消息循环集成?

时间:2011-10-12 21:52:52

标签: c# asynchronous async-ctp async-await

我没有机会查看新C#async / await功能的CTP,但这里有些我想知道:

它如何与消息循环集成?我假设在标准的Windows应用程序(Winforms,WPF)中,通过使用Dispatcher或类似的方式将消息发送到应用程序的消息循环来调用延续?

如果我没有使用标准的Windows消息循环怎么办?例如,在GTK#应用程序或控制台应用程序中(如果在控制台应用程序中确实可以使用此功能)。

我在互联网上搜索了相关信息,但无济于事。谁能解释一下?

2 个答案:

答案 0 :(得分:5)

它使用System.Threading.SynchronizationContext.Current。 WPF和Winforms都安装了自己的SynchronizationContext版本。使用他们的消息循环来编组从工作线程回到主UI线程的调用。分别使用Dispatcher.Begin / Invoke和Control.Begin / Invoke()。

在控制台模式应用程序中完成此操作并不容易,其主线程没有明确定义的“空闲”状态,允许以安全的方式注入封送的方法调用,以避免重新入侵的麻烦。你当然可以添加它,但你将重新发明消息循环。

答案 1 :(得分:4)

这一切都归结为“等待者”对延续过程所做的事情。

BCL中Task<T>的实现将使用当前的同步上下文(unless you ask it not to using ConfigureAwait) - 这意味着在WPF / SilverLight中它将使用调度程序;在Windows窗体中,它将使用类似Control.BeginInvoke的东西,并且在线程池线程中它将继续在任何线程池线程上运行。请注意,它是当前上下文在await表达式处的重要部分,因为这是任务将为继续运行而捕获的内容。

链接的博客文章(由Mads Torgersen撰写)很好地解释了它如何在幕后工作,我有一个series of blog posts你可能会觉得有用。