2012-10-10 40 views
1

我們有一個已經建立的,大大多平臺的代碼庫,目前正在移植到WinRT。我們面臨的挑戰之一是如何處理WinRT的異步風格。如何將WinRT異步任務集成到現有的同步庫中?

例如,我們不確定如何處理WinRT的異步文件操作。毫不奇怪,我們的代碼庫的API是同步的。一個典型的例子是我們的File :: Open函數,它試圖打開一個文件並返回成功或失敗。我們如何調用WinRT函數並保持函數的行爲一致?

請注意,我們不幸受到遺留問題的限制:我們不能簡單地將API更改爲異步。

謝謝!

+0

認真思考Stephen Toub的[我應該公開異步方法的同步包裝?](http://blogs.msdn.com/b/pfxteam/archive/2012/04/13/10293638.aspx) - 這是一個經典。 –

+0

我會看看它,謝謝! – djcouchycouch

回答

6

我假設您希望重新實現庫來支持WinRT應用程序,同時不改變API的定義,以便現有的應用程序保持兼容。

我認爲如果在調用異步方法時不包含await關鍵字,則不會執行異步操作,而應該以同步方式執行。但如果方法返回一個值(根據我的經驗),它確實不起作用。

我一直在使用這個代碼,以使文件操作同步:

IAsyncOperation<string> contentAsync = FileIO.ReadTextAsync(file); 
contentAsync.AsTask().Wait(); 
string content = contentAsync.GetResults(); 
+1

請注意,在許多情況下,這可能會導致死鎖,因爲您正在等待的操作可能需要在您正在等待的線程上處理事件,從而阻止事件的處理。 –

+0

那麼還有什麼其他模式可以使異步呼叫同步?在我的應用程序中,我希望確保在應用程序顯示初始屏幕前閱讀此配置信息,因此我必須等待某處完成此代碼... @FilipSkakun –

+1

@MattiasLindberg使用'ConfigureAwait(false);'而不是'Wait()',所以它會在後臺線程中執行。 –

2

如果你想與不支持的平臺分享你的代碼異步/ AWAIT - 你可能會更好過有對於老平臺不同的API,而新的帶開關一樣

#if SILVERLIGHT 
#elif NETFX_CORE 
#elif WPF 
#endif 

最終異步API是有可能在較舊的平臺出現了,你實際上可以包裝非異步調用到任務,使他們異步如果他們別。強制異步方法同步工作必然會讓你很快退縮。例如,您的WinRT應用程序可能會停止響應幾秒鐘,並被操作系統殺死。或者你可能會遇到死鎖,等待任務完成並阻止他們嘗試完成的線程。

+0

可能更好,但不可能。正如我在帖子中提到的那樣,API是古老而且非常堅固的。預計構建在代碼庫上的應用程序可以構建並且沒有或幾乎不做任何更改。至於響應性,主要的應用程序代碼仍然在單獨的線程中運行,所以UI不受影響。 – djcouchycouch

+0

無法編輯原始評論:構建於代碼庫上的應用程序預計將在不同或幾乎沒有更改的平臺上構建和工作。 – djcouchycouch