Оба возможны.Если метод на самом деле async
(т. Е. Использует ключевое слово C # async
в объявлении), то компилятор C # оборачивает его таким образом, что он всегда будет надежно выдавать await
, но важнообратите внимание, что это не единственный способ написать метод, который может быть await
-еданным, поэтому: если вы не управляете вызываемым методом (ThisMethodWillThrow
) и не можете положиться наЗная о реализации, было бы лучше, чтобы try
включил начальный вызов, а также await
.
В качестве примера метода, который будет генерировать немедленно, а не в * 1012.*:
Task ThisMethodWillThrow() { // note that this is **not** "async", but is awaitable
if (thingsAreBad) throw new SomeException();
return SomeInnerMethod();
}
async Task SomeInnerMethod() { ... }
Это может заманчиво подумать «хорошо, просто сделайте все приемлемые методы async
, чтобы избежать этого» - как:
async Task ThisMethodWillThrowToo() { // note that this is "async"
if (thingsAreBad) throw new SomeException();
await SomeInnerMethod();
}
Однако: существуют сценарии, в которых асинхронный механизм представляет собой очень измеримую нагрузку на производительность в случае «часто синхронизируемого, иногда асинхронного» - и поэтому общая оптимизация в критичном к производительности ожидаемом коде (например, код ввода-вывода / сети) составляет активно избегать механизм async
, если мы не знаем, что мы на самом деле падаем в асинхронный путь.