TGViewer
НеСерьезный шарпист НеСерьезный шарпист @serious_seesharp · 2.4K subscribers
Post #68 3.36K
Вызов асинхронных методов в синхронном коде

В C# код, использующий асинхронность, должен следовать принципу: "async всё", то есть если есть асинхронный метод, его нужно вызывать в асинхронном контексте. Однако бывает возникают ситуации, когда нужно вызвать асинхронный метод из синхронного кода (например, в старом коде, в desktop UI-приложениях).

Существуют несколько подходов для таких вызовов, рассмотрим основные из них:

1. Task.Result и Task.Wait()
Самый простой способ — использовать свойство Result или метод Wait(), чтобы блокировать выполнение до завершения асинхронной задачи.
public int GetCountMethod()
{
var task = GetCountMethodAsync();
task.Wait()

return task.Result;
}

или
public int GetCountMethod()
{
var task = GetCountMethodAsync();

return task.Result;
}


Task.Wait() метод блокирует поток до тех пор, пока не taskбудет успешно выполнен. Task.Result также блокирует вызывающий поток, пока результат не готов, как только задача будет завершена, возвращается результат.

Основной проблемой данного способа является возможный deadlock, который может произойти, если вызывающий поток ожидает завершения асинхронной задачи, которая пытается вернуться на основной поток для выполнения продолжения из-за контекста синхронизации, что может произойти в UI-приложениях.

Еще одним минусом является то, что в случае возникновения исключения оно будет обернуто в AggregateException, который придется раскручивать для получения действительного исключения.

2. GetAwaiter().GetResult()
Данный способ аналогичен предыдущему, но будет более предпочтительнее, т.к. не оборачивает возникающие исключения в AggregateException.
public int GetCountMethod()
{
var result = GetCountMethodAsync().GetAwaiter().GetResult();

return result;
}


Однако такой подход также может привести к deadlock'ам

3. Task.Run()
Можно использовать Task.Run() для выполнения асинхронного кода в отдельном фоновом потоке, что решает проблему deadlock.
public int GetCountMethod()
{
var result = Task.Run(async () => await GetCountMethodAsync()).GetAwaiter().GetResult();

return result;
}


4. async Main
А для того, чтобы не использовать весь этот цирк, если планируем использовать асинхронный код, то делаем асинхронную точку входа.
  • 👍 24
  • 🔥 7
  • ❤ 3
  • 👎 2
More from @serious_seesharp
  1. Jul 11, 2026Знакомый создал бота @booster_tbot, для прохождения мок-собесов бесплатно, а вопросы основ…
  2. Jun 30, 2025Всем, привет! Мы сейчас начинаем отбор докладов на осеннюю конфу "Стачка" в Питере. Если у…
  3. Jun 28, 2025Столкнулся с тем, что, как выяснилось, не всем очевидно для чего нужен ValueTask и когда е…
  4. Jun 5, 2025Post #85
  5. May 24, 2025Давно хотел сделать розыгрыш, и вот, кажется, время настало 🥰 Не надо никуда ничего скиды…
  6. May 23, 2025👩‍💻 Когда в C# 12 появились primary constructors (первичные конструкторы класс/структур)…
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 →