假设我要编写一个异步方法 M。我不知道会使用什么样的同步上下文(UI、ASP.NET、控制台应用程序等)来调用它。我想让该方法尽可能易于使用。这意味着任何人都应该能够通过访问返回任务的 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 时忘记同步上下文的一种解决方案是将 M 的内容包装在 Task.Run 中。但是,这将强制线程跳转,包括在 M 中的所有任务都已完成并且所有内容都可以在同一个线程上同步运行而无需上下文切换的情况下。有没有更好的解决方案来忘记线程的同步上下文?或者我是否遗漏了一些东西,这会使这个问题变得无关紧要?