TGStat
TGStat
Введите текст для поиска
Расширенный поиск каналов
  • flag Russian
    Язык сайта
    flag Russian flag English flag Uzbek
  • Вход на сайт
  • Каталог
    Каталог каналов и чатов Региональные подборки Тематические подборки Платные каналы Поиск каналов
    Добавить канал/чат
  • Рейтинги
    Рейтинг каналов Рейтинг чатов Рейтинг публикаций
    Рейтинги брендов и персон
  • Аналитика
  • Поиск по публикациям
  • Мониторинг Telegram
  • Продвижение
    Реклама через Яндекс Бизнес Реклама в каналах через TGStat Agency Реклама на сайте TGStat.ru
НеСерьезный шарпист

23 Dec 2024, 17:58

Открыть в Telegram Поделиться Пожаловаться

Вызов асинхронных методов в синхронном коде

В 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
А для того, чтобы не использовать весь этот цирк, если планируем использовать асинхронный код, то делаем асинхронную точку входа.

2.2k 0 36 9 35
Каталог
Каталог каналов и чатов Подборки каналов Поиск каналов Добавить канал/чат
Рейтинги
Рейтинг каналов Telegram Рейтинг чатов Telegram Рейтинг публикаций Рейтинги брендов и персон
API
API статистики API поиска публикаций API Callback
Наши каналы
@TGStat @TGStat_Chat @telepulse @TGStatAPI
Почитать
Академия TGStat Исследование Telegram 2019 Исследование Telegram 2021 Исследование Telegram 2023
Контакты
Справочный центр Поддержка Почта Вакансии
Всякая всячина
Пользовательское соглашение Политика конфиденциальности Публичная оферта
Наши боты
@TGStat_Bot @SearcheeBot @TGAlertsBot @tg_analytics_bot @TGStatChatBot