Быть или не быть async/await
В коде
async Task<Result> Work()
{
var data = await GetData();
//do something
}
Есть два варианта написания GetData
async Task<object> GetData()
{
await Service.GetDataAsync();
}
или
Task<object> GetData()
{
return Service.GetDataAsync();
}
Значительна ли разница между методами?
Что лучше по производительности?
Что происходит под "капотом" в данном случае с async/await в двух словах?
Ответы (1 шт):
Тема много где описана.
Кратко: по ключевому слову async компилятор генерит асинхронную машину состояний из метода. Это достаточно сложная система, чтобы await смог в ней работать правильно.
Во втором случае вы выполнили оптимизацию, то есть убрали машину состояний, потому что если бы даже она была, у нее было бы всего одно значимое состояние (всего два).
Поэтому второй метод быстрее. Но эта оптимизация далеко не всегда доступна.
Например эта конструкция не будет работать.
// не сработает
Task<object> GetData()
{
try
{
return Service.GetDataAsync();
}
catch
{
}
}
Потому что возврат Task из метода произойдет раньше, чем сам метод отработает, логично же? Поэтому перехват исключения здесь возможен только из стартовой синхронной части вызываемого метода.
И эта тоже не будет работать.
// не сработает
Task<object> GetData()
{
using var obj = new MyDispoasbleObject();
return Service.GetDataAsync(obj);
}
Потому что объект obj будет уничтожен раньше, чем метод GetDataAsync завершится.
Ну и если в асинхронном методе более одного await, либо имеющийся один await не в конце метода - такая оптимизация в принципе не доступна.