最佳答案
我正在更新一个内置了 API 外观的库。NET 3.5.因此,所有方法都是同步的。我不能更改 API (例如,将返回值转换为 Task) ,因为这将要求所有调用方都更改。因此,我留下了如何以同步方式最好地调用异步方法的问题。这是在 ASP.NET 4、 ASP.NET Core 和。NET/.NET 核心控制台应用程序。
我可能还不够清楚——现在的情况是,我有不能异步感知的现有代码,我想使用新的库,比如 System。网。Http 和仅支持异步方法的 AWS SDK。因此,我需要弥合这一差距,并能够拥有可以同步调用但随后可以在其他地方调用异步方法的代码。
我做了很多阅读,有很多次,这已经被问到和回答。
问题是大多数的答案是不同的!我见过的最常见的方法是使用。结果,但这可能会陷入僵局。我尝试了以下所有方法,它们都有效,但我不确定哪种方法是避免死锁、具有良好性能以及与运行时良好配合的最佳方法(在尊重任务调度程序、任务创建选项等方面)。有明确的答案吗?最好的方法是什么?
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;
}