2013-05-30 44 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为伟大的链接!必须为构建框架的人阅读 –