Я в процесі оновлення бібліотеки, яка має поверхню API, вбудовану в .NET 3.5. В результаті всі методи є синхронними. Я не можу змінити API (тобто перетворити повернені значення в Завдання), тому що для цього потрібно буде змінити всі абоненти. Тож я залишаюся з тим, як найкраще викликати асинхронні методи синхронно. Це стосується консольних програм ASP.NET 4, ASP.NET Core та .NET / .NET Core.
Можливо, я був недостатньо чітким - ситуація полягає в тому, що я маю існуючий код, який не знає асинхронізацію, і я хочу використовувати нові бібліотеки, такі як System.Net.Http та AWS SDK, які підтримують лише асинхронні методи. Тому мені потрібно подолати розрив і мати можливість мати код, який можна викликати синхронно, але потім можна викликати асинхронні методи в іншому місці.
Я багато читав, і неодноразово про це запитувались і відповідали.
Виклик асинхронного методу з неасинхронного методу
Синхронно чекаючи асинхронної операції, і чому функція Wait () заморожує програму тут
Виклик асинхронного методу з синхронного методу
Як запустити метод асинхронного завдання <T> синхронно?
Виклик асинхронного методу синхронно
Як викликати асинхронний метод із синхронного методу в C #?
Проблема в тому, що більшість відповідей різні! Найпоширеніший підхід, який я бачив, - використання .Result, але це може зайти в глухий кут. Я спробував усі наступні дії, і вони працюють, але я не впевнений, що найкращий підхід уникнути тупикових ситуацій, мати хорошу продуктивність і чудово грати з робочим середовищем (з точки зору вшанування планувальників завдань, опцій створення завдань тощо). ). Чи існує остаточна відповідь? Який найкращий підхід?
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;
}