2011-10-12 58 views
8

我還沒有機會看看C#的異步/等待新功能的CTP,但我想知道的是:C#5中的新異步/等待功能如何與消息循環集成?

它如何與消息循環集成?我假設在一個標準的Windows應用程序(Winforms,WPF)中,通過使用Dispatcher或類似的函數嚮應用程序的消息循環發送消息來調用continuations?

如果我不使用標準的Windows消息循環會怎麼樣?例如,在GTK#應用程序或控制檯應用程序中(如果在控制檯應用程序中確實可以使用該功能)。

我已經在互聯網上搜索有關此信息,但無濟於事。誰能解釋一下?

回答

5

它使用System.Threading.SynchronizationContext.Current。 WPF和Winforms都安裝了自己的SynchronizationContext版本。它們使用它們的消息循環將來自工作線程的調用封送回主UI線程。分別使用Dispatcher.Begin/Invoke和Control.Begin/Invoke()。

在控制檯模式應用程序中完成這項工作並不容易,它的主線程沒有一個定義良好的'空閒'狀態,允許以安全的方式注入封送的方法調用,以避免再次出現頭痛問題。你當然可以添加它,但你會重新發明消息循環。

+0

謝謝Hank。嘗試考慮在控制檯應用程序中使用異步並失敗的情況。所以我認爲在這種情況下缺乏同步環境大多是沒有意義的。 – Grokys

+3

[AsyncEx](http://nitoasyncex.codeplex.com/)包含一個[AsyncContext](http://nitoasyncex.codeplex.com/wikipage?title=AsyncContext)類,它爲控制檯應用程序提供異步兼容的主循環(和單元測試)。 –

+0

更多關於'SynchronizationContext' [這裏](http://msdn.microsoft.com/en-us/magazine/gg598924.aspx)。 –

4

這一切都歸結爲「awaiter」在繼續傳遞時所做的事情。

BCL中Task<T>的實現將使用當前的同步上下文(unless you ask it not to using ConfigureAwait) - 這意味着在WPF/SilverLight中它將使用調度程序;在Windows窗體中,它將使用類似Control.BeginInvoke的東西,並且在線程池線程中它只會在任何線程池線程上運行。請注意,這是您當前的上下文在等待表達這一點很重要,因爲這是任務將捕獲的延續運行。

鏈接的博客文章(由Mads Torgersen撰寫)很好地解釋了它如何在隱藏條件下工作,並且我有一個series of blog posts,您可能也會發現它。

+0

謝謝喬恩。在我所有的.Net域遊覽中,我從來沒有遇到SynchronizationContext.Current,這是我認爲你的意思是「當前同步上下文」?每天學些新東西。 – Grokys

+1

@格洛斯基:是的。 Stephen Toub的關於異步性能的文章還有更多:http://msdn.microsoft.com/en-us/magazine/hh456402.aspx –