2013-05-30 39 views
4

假設我想寫一個異步方法M.我不知道將使用什麼樣的同步上下文(UI,ASP.NET,控制檯應用程序等)稱它。我想讓這個方法儘可能簡單易用。這意味着任何人都應該能夠通過訪問返回的Task的Result成員來同步調用它。如何忘記c中的異步方法中的同步上下文

public async Task<int> M() 
{ 
    // lot's of calling of helper methods including awaits, etc. 
    // helper methods not owned by me 
    // ... 

    return 42; 
} 


// this should be safe to do from any synchronization context 
int result = M().Result; // Synchronously wait 

的問題是方法M的調用程序的同步上下文泄漏到M的被調用者。如果他們中的任何一個希望繼續在同步方面的通過,那麼它可以死鎖(例如,當使用UI同步上下文)。

調用M時忘記同步上下文的一種解決方案是在Task.Run中包裝M的內容。但是,這將強制線程跳轉,包括M內的所有任務都完成,並且所有內容都可以在沒有上下文切換的情況下在同一線程上同步運行。有沒有更好的解決方案來忘記線程的同步上下文?或者我錯過了什麼,這會使這個問題變得無關緊要?

回答

3

我想使該方法儘可能易於使用。這意味着任何人都應該能夠通過訪問返回的Task的Result成員來同步調用它。

有沒有簡單的方法create a synchronous wrapper for an asynchronous method。最好讓異步方法是異步的。

可以使用ConfigureAwait(continueOnCapturedContext: false)丟棄的背景下,但它不會在你的情況下,任何比Task.Run,因爲你不能改變M呼叫的方法。

+0

+1爲偉大的鏈接!必須爲構建框架的人閱讀 –