Muszę wywołać async
metodę w catch
bloku przed ponownym rzuceniem wyjątku (z jego śladem stosu) w następujący sposób:
try
{
// Do something
}
catch
{
// <- Clean things here with async methods
throw;
}
Ale niestety nie możesz używać await
w a catch
or finally
block. Dowiedziałem się, że to dlatego, że kompilator nie ma sposobu, aby wrócić w catch
bloku, aby wykonać to, co jest po twojej await
instrukcji lub coś w tym rodzaju ...
Próbowałem użyć Task.Wait()
do wymiany await
i dostałem impasu. Szukałem w Internecie, jak mogę tego uniknąć i znalazłem tę witrynę .
Ponieważ nie mogę zmienić async
metod ani nie wiem, czy używają ConfigureAwait(false)
, stworzyłem te metody, które pobierają a, Func<Task>
która uruchamia metodę asynchroniczną, gdy jesteśmy w innym wątku (aby uniknąć impasu) i czeka na jej zakończenie:
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());
}
Więc moje pytania brzmi: czy uważasz, że ten kod jest w porządku?
Oczywiście, jeśli masz jakieś ulepszenia lub znasz lepsze podejście, słucham! :)
await
w bloku catch jest faktycznie dozwolony od C # 6.0 (patrz moją odpowiedź poniżej)