非同期メソッド 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 が呼び出されたときに同期コンテキストを忘れる 1 つの解決策は、M の内容を Task.Run でラップすることです。ただし、M 内のすべてのタスクが完了し、すべてがコンテキスト スイッチなしで同じスレッド上で同期的に実行できる場合を含め、スレッド ジャンプが強制されます。スレッドの同期コンテキストを忘れるためのより良い解決策はありますか? それとも、この質問を無関係にする何かが欠けていますか?