Comments 8
Например добавить вачдог на тиньке, который в проблемной ситуации будет перезапускать всю систему.
Есть одна проблема. Await блокирует вызывающий поток и весь смысл асинхронности теряется. Так что код который вы написали не асинхронный аж никак.
Наверное, мои вопросы будут скорее к оригиналу, нежели к Вашему переводу. Но всё же.
Отсутствует полный исходный код примеров. В частности, что в оригинале, что в переводе отсутствует код метода PassTheTime.
Асинхронность в .net, к большому сожалению не настолько проста, как описывается в статье =(( Наверное, стоило бы в заключение дать ссылки либо на другие примеры использования, либо на более глубоко разбираемые примеры по async-await.
В приведенном примере синхронного кода если, например, внутри метода BakeCake() вывалится Exception — это прервет выполнение всех последующих методов.
А вот для асинхронного кода уже начинаются вариации. Похожий пример описан в блоге Stephen Cleary: https://blog.stephencleary.com/2016/12/eliding-async-await.html (раздел Exceptions).
Поясню на примере.
Пусть код метода BakeCakeAsync выглядит так:
public static async Task<bool> BakeCakeAsync(bool isPreheated)
{
if (!isPreheated)
throw new InvalidOperationException("before 1st await");
var result = await InnerBakeCakeAsync(isPreheated).ConfigureAwait(false);
if (isPreheated)
throw new InvalidOperationException("after await");
return result;
}
Так вот: если метод вызовется isPreheated = true, то исключение в основном методе "поймается" на строке
Task<bool> bakeCakeTask = BakeCakeAsync(isPreheated);
И AddFrostingIngredients не будет вызван.
А вот если вызвать BakeCakeAsync вызовется с isPreheated = false, то исключение "поймается" уже только на строке с await-ом:
bool isBaked = await bakeCakeTask;
И получается, что AddFrostingIngredients вполне себе успеет выполниться
То есть при определенных условиях мы подготовим замороженные ингредиенты к приготовлению не посмотрев даже, что с процессом выпекания что-то не так.
Так вот: если метод вызовется isPreheated = true, то исключение в основном методе "поймается" на строке Task<bool> bakeCakeTask = BakeCakeAsync(isPreheated);
И AddFrostingIngredients не будет вызван.
Вы это проверяли? Насколько я знаю, в любом случае исключение будет "спрятано" в возвращаемый Task, независимо от положения относительно первого await.
Вы это проверяли?
Там все немного хитрее. Если BakeCakeAsync
— async
, то обернется. А если нет, то есть вот так:
public static Task<bool> BakeCakeAsync(bool isPreheated)
{
if (!isPreheated)
throw new InvalidOperationException();
return InnerBakeCakeAsync(isPreheated);
}
то не обернется. При этом преобразование одного в другое — частая вещь, когда люди не хотят лишних накладных расходов на стейт-машины, или, наоборот, когда код усложняется.
А со стороны вызывающего кода эти варианты имплементации и вовсе неотличимы, поэтому он должен быть готов, что эксепшн будет брошен как на вызове метода, так и на эвейте таска.
Как я понимаю асинхронный код?