Я хочу сделать синхронный метод асинхронным.
Да, я знаю, что это плохая практика, но есть несколько причин, в которых мы нуждаемся, и поэтому давайте предположим, ради этого вопроса, что мы должны это сделать, и другого способа достичь конечного результата нет.
Итак, у меня есть мой асинхронный метод
public static async Task AsyncMethod();
Если я назову это так:
public static void SyncMethod()
{
Task task = Task.Run(async () => { await AsyncMethod(); });
task.Wait();
}
все отлично работает.
Но если я хочу обобщить свой подход и поместить эту логику в отдельный метод, в библиотеку утилит (такая библиотека является отдельной от моего проекта UWP), метод никогда не вернется. Вот код с подходом, который не работает:
public static class Utilities
{
public static void Sync(this Task task)
{
if (task == null)
return;
Task t = Task.Run(async () =>
{
try
{
await task;
}
catch (Exception e)
{
s_log.InfoFormat("Exception while running task {0} due to {1}", task.Id, e.Message);
}
});
t.Wait();
}
}
И для вызова метода я просто делаю:
public static void SyncMethod()
{
AsyncMethod().Sync();
}
Кто-нибудь может объяснить эту дихотомию, пожалуйста?
EDIT:
В связи с ранними комментариями к вопросам позвольте мне уточнить конечную цель этого вопроса.
Проблема не в том, как решить синхронизацию против асинхронного паттерна. У меня уже есть хорошее решение для этого, и я объясняю это в первой части вопроса.
Более того, есть еще один вопрос ( Вызов асинхронного метода из методов действия синхронизации: Task.Run или ConfigureAwaits (false) ), который объясняет плюсы и минусы решения и т. Д.
Вместо этого проблема заключается в понимании того, почему эти 2 строки кода
Task task = Task.Run(async () => { await AsyncMethod(); });
task.Wait();
работает "in-line", но если я помещу их в другой метод (в другую библиотеку), они больше не будут работать.
Пожалуйста, найдите MVCE здесь: https://github.com/cghersi/UWPExamples/tree/master/SyncAntiPattern