假设我想编写一个异步方法M.我不知道将使用哪种同步上下文(UI,ASP.NET,控制台应用程序等)来调用它。我想让方法尽可能易于使用。这意味着任何人都应该能够通过访问返回的Task的Result成员来同步调用它。
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中的所有任务都完成且所有内容可以在没有上下文切换的情况下在同一线程上同步运行的情况下。有没有更好的解决方案忘记线程的同步上下文?或者我错过了什么,这会使这个问题无关紧要?
答案 0 :(得分:3)
我想让方法尽可能易于使用。这意味着任何人都应该能够通过访问返回任务的Result成员来同步调用它。
create a synchronous wrapper for an asynchronous method没有简单的方法。最好让异步方法异步。
你可以使用ConfigureAwait(continueOnCapturedContext: false)
来放弃上下文,但在你的情况下它不会比Task.Run
更好,因为你无法改变M
的方法{1}}来电。