Мені потрібно викликати async
метод у catch
блоці, перш ніж знову викидати виняток (з його трасуванням стека), як це:
try
{
// Do something
}
catch
{
// <- Clean things here with async methods
throw;
}
Але, на жаль, ви не можете використовувати await
а catch
чи finally
блок. Я дізнався, що це тому, що компілятор не має способу повернутися назад у catch
блок, щоб виконати те, що є після вашої await
інструкції або щось подібне ...
Я намагався використати Task.Wait()
для заміни, await
і я отримав глухий кут. Я шукав в Інтернеті, як мені цього уникнути, і знайшов цей сайт .
Оскільки я не можу змінити async
методи, і я не знаю, чи використовують вони ConfigureAwait(false)
, я створив ці методи, які беруть Func<Task>
метод, який запускає асинхронний метод, коли ми потрапляємо в інший потік (щоб уникнути тупикової ситуації), і чекає його завершення:
public static void AwaitTaskSync(Func<Task> action)
{
Task.Run(async () => await action().ConfigureAwait(false)).Wait();
}
public static TResult AwaitTaskSync<TResult>(Func<Task<TResult>> action)
{
return Task.Run(async () => await action().ConfigureAwait(false)).Result;
}
public static void AwaitSync(Func<IAsyncAction> action)
{
AwaitTaskSync(() => action().AsTask());
}
public static TResult AwaitSync<TResult>(Func<IAsyncOperation<TResult>> action)
{
return AwaitTaskSync(() => action().AsTask());
}
Тож мої запитання: Чи вважаєте ви, що цей код нормальний?
Звичайно, якщо у вас є якісь вдосконалення або ви знаєте кращий підхід, я слухаю! :)
await
в блоці catch фактично дозволено з C # 6.0 (див. Мою відповідь нижче)