TGViewer
.NET Разработчик .NET Разработчик @netdeveloperdiary · 6.75K subscribers
Post #680 1.24K
День пятьсот пятьдесят шестой. #ЗаметкиНаПолях
Асинхронный Mетод без async в C#

Недавно я изменил сигнатуру метода действия контроллера следующим образом:
public async Task GetRecordAsync(int id)
=> await repo.GetAsync(id);

на
public Task GetRecordAsync(int id)
=> repo.GetAsync(id);


Во время код-ревью члены моей команды быстро заметили это и поставили под сомнение удаление ключевых слов async и await. Сначала я согласился, что это выглядит сомнительно. Даже после объяснения, которое приведено ниже, может быть полезно их вернуть, чтобы другие на этом не спотыкались.

Итак, мы можем безопасно опустить async/await, поскольку вызывающий метод GetRecordAsync в конечном итоге возвращает то же, что и вызываемый, repo.GetAsync. Вместо того, чтобы наш метод ожидал завершения задачи и возвращал результат, он передаёт эту работу вызывающей стороне.

Вы всегда можете ожидать Task, потому что он предоставляет API обратного вызова, который позволяет платформе сообщать, какой код выполнять после завершения асинхронной операции.

Подробнее про работу async/await

Удаление ключевых слов async/await предотвращает создание конечного автомата. Это немного снижает накладные расходы на выполнение метода. Хотя я не удивлюсь, если компилятор достаточно умён, чтобы оптимизировать этот момент.

Ловушки отсутствия async/await
1. Отсутствие методов в трассировке стека
Рассмотрим следующую цепочку методов:
static async Task Top() => await Middle();
static Task Middle() => Bottom();
static async Task Bottom() {
await Task.Delay(10);
throw new Exception("Bottom Exception");
}

При вызове Top(), трассировка стека не будет включать вызов Middle():
System.Exception: Bottom Exception
at ConsoleApp1.Bottom()
at ConsoleApp1.Top()
at ConsoleApp1.Program.Main(String[] args)


2. Отмена Заданий при Использовании using
Код ниже приводит к ошибке TaskCanceledException:
Task<string> Using HttpClient() {
using var client = new HttpClient();
return client.GetStringAsync("https://1.1.1.1");
}

Это происходит потому, что объект HttpClient удаляется до того, как завершается асинхронный запрос, тем самым отменяя все текущие запросы.

Итого
В общем случая я бы не рекомендовал удалять async/await. Как говорится, преждевременная оптимизация - это корень зла. Можно рассмотреть удаление ключевых слов, если:
- Асинхронный метод - это просто звено в цепочке вызовов.
- Метод находится на «горячем» участке кода.

Источник: https://drakelambert.dev/2020/07/Asynchronous-Method-Without-async-in-C%23
  • 👍 1
More from @netdeveloperdiary
  1. Sep 30, 2026Post #3356
  2. Sep 29, 2026Фото 3 (с) Анатолий Кулаков
  3. Sep 29, 2026День 2799. Конференция DotNext 2026. Часть 1 25 и 26 сентября в Москве прошла очередная ко…
  4. Sep 28, 2026День 2798. #Оффтоп Утиная Типизация в C# с Помощью Перехватчиков. Часть 2 Некоторое время…
  5. Sep 27, 2026День 2797. #ЗаметкиНаПолях #AI Рабочий процесс с Copilot для .NET. Окончание Начало Продол…
  6. Sep 26, 2026День 2796. #ЗаметкиНаПолях #AI Рабочий процесс с Copilot для .NET. Продолжение Начало Три…
Threads Profile ViewerView any public Threads profile without an account.Open ThreadLook →Writing with AI? Make it sound human.Metric37 rewrites AI drafts so they read naturally. Free AI detector, 1,500 words free.Try Metric37 →