.NET 3.5でビルドされたAPIサーフェスを持つライブラリを更新中です。その結果、すべてのメソッドが同期します。すべての呼び出し元を変更する必要があるため、APIを変更することはできません(戻り値をタスクに変換する)。ですから、非同期メソッドを同期的に呼び出す方法が残っています。これは、ASP.NET 4、ASP.NETコア、および.NET/.NETコアコンソールアプリケーションのコンテキストにあります。非同期コードから非同期メソッドを呼び出す
私は、非同期認識ではない既存のコードがあり、非同期メソッドのみをサポートするSystem.Net.HttpやAWS SDKなどの新しいライブラリを使用したいという状況が十分にはっきりしていない可能性があります。だから私はギャップを橋渡しする必要があり、同期的に呼び出すことができるコードを持つことができるが、別の場所で非同期メソッドを呼び出すことができる。
私は多くの読書をしましたが、これは尋ねられ、答えられた回数があります。
Calling async method from non async method
Synchronously waiting for an async operation, and why does Wait() freeze the program here
Calling an async method from a synchronous method
How would I run an async Task<T> method synchronously?
Calling async method synchronously
How to call asynchronous method from synchronous method in C#?
問題はほとんどの回答が異なっていることです!私が見た最も一般的なアプローチはuseResultですが、これはデッドロックする可能性があります。私は以下のすべてを試してみましたが、うまくいきましたが、デッドロックを回避し、パフォーマンスが良く、実行時にうまくいきます(タスクスケジューラ、タスク作成オプションなどを尊重する上で最良の方法はわかりません)。 )。決定的な答えはありますか?最善のアプローチは何ですか?
private static T taskSyncRunner<T>(Func<Task<T>> task)
{
T result;
// approach 1
result = Task.Run(async() => await task()).ConfigureAwait(false).GetAwaiter().GetResult();
// approach 2
result = Task.Run(task).ConfigureAwait(false).GetAwaiter().GetResult();
// approach 3
result = task().ConfigureAwait(false).GetAwaiter().GetResult();
// approach 4
result = Task.Run(task).Result;
// approach 5
result = Task.Run(task).GetAwaiter().GetResult();
// approach 6
var t = task();
t.RunSynchronously();
result = t.Result;
// approach 7
var t1 = task();
Task.WaitAll(t1);
result = t1.Result;
// approach 8?
return result;
}
あなたは答えていません。非同期的な新しいメソッドを追加し、レガシーの呼び出し元に対して古い同期メソッドを保持します。 –
これはちょっと厳しいようで、新しいコードを使用する能力を本当になくします。たとえば、AWS SDKの新しいバージョンには、非同期メソッドはありません。他の多くの第三者図書館でも同じです。あなたが世界を書き直さない限り、あなたはこれらのどれも使うことができないのですか? –
オプション8:[TaskCompletionSource](https://msdn.microsoft.com/en-us/library/dd449174(v = vs.110).aspx)がオプションになる可能性がありますか? – OrdinaryOrange