Squeak.ru - шаблоны программирования

Что происходит с потоком вызываемого, когда асинхронная функция вызывается синхронно

В приведенном ниже примере, когда асинхронная функция «Process» вызывается синхронно, я вижу, что вызов «await Task.Delay (1000)» приводит к зависанию пользовательского интерфейса.

Я знаю, что могу избежать зависания, либо вызвав «await Task.Delay (1000) .ConfigureAwait (false)», либо заключив вызов «Process» в другую задачу. Я понимаю, что проблема связана с контекстом синхронизации, и я знаю, что await делает с ним что-то необычное, например, если я заменю вызов «await Task.Delay (1000)» на «Task.Delay (1000) .Wait ()» пользовательского интерфейса не зависает.

Может кто-нибудь объяснить поведение (я пытался посмотреть код ildasm, но это не помогло). Большое спасибо.

public MainWindow()
{
    InitializeComponent();
    Loaded += OnLoaded;
}

public async void OnLoaded(object sender, RoutedEventArgs args)
{
    var task = Process();
    MessageBox.Show(task.Result);
}

public async Task<String> Process()
{
    await Task.Delay(1000);
    return "";
}

  • Вкратце: task.Result означает зависание пользовательского интерфейса до завершения задачи, а затем использование результата. await task означает передать управление вызывающей стороне; когда задача завершена, запланируйте продолжение задачи, чтобы она выполнялась в удобное время в будущем, и затем используйте результат. 06.07.2013

Ответы:


1

Во-первых, методы всегда вызываются синхронно. Когда вызывается OnLoaded, он вызывает метод Process.

Метод Process вызывает метод Task.Delay и возвращает ссылку на объект Task<string>, который он ожидает. Это означает, что код после await выполняется позже и что метод Process возвращается в этот момент.

Метод OnLoaded возвращает ссылку на объект Task<string>, который он хранит в переменной task. Затем вызывает метод получения Result для задачи. Это блокирует текущий поток до завершения задачи.

Через секунду метод Process пытается продолжить. Поскольку вы запустили задачу в потоке пользовательского интерфейса, планировщик пытается запланировать метод Process в потоке пользовательского интерфейса. Но поток пользовательского интерфейса заблокирован вызовом Result геттера, поэтому оператор return ""; никогда не выполняется.

06.07.2013
  • Извините, но это не так, пользовательский интерфейс зависает, и возврат даже не вызывается (установите точку останова и убедитесь в этом сами). 06.07.2013
  • Спасибо, не знаю, почему мне это не понравилось. :) 06.07.2013
  • +1. Я описываю этот тупик более подробно в моем блоге и статья MSDN, а в моем сообщении в блоге есть ссылки на другие информация, включая пару демонстраций тупика. 06.07.2013
  • Новые материалы

    Угловая структура архитектуры
    Обратите внимание, что эта статья устарела, я решил создать новую с лучшей структурой и с учетом автономных компонентов: https://medium.com/@marekpanti/angular-standalone-architecture-b645edd0d54a..

    «Данные, которые большинство людей используют для обучения своих моделей искусственного интеллекта, поставляются со встроенным…
    Первоначально опубликовано HalkTalks: https://hacktown.com.br/blog/blog/os-dados-que-a-maioria-das-pessoas-usa-para-treinar-seus-modelos-de-inteligencia-artificial- ja-vem-com-um-vies-embutido/..

    Сильный ИИ против слабого ИИ: различия парадигм искусственного интеллекта
    В последние годы изучению и развитию искусственного интеллекта (ИИ) уделяется большое внимание и прогресс. Сильный ИИ и Слабый ИИ — две основные парадигмы в области искусственного интеллекта...

    Правильный способ добавить Firebase в ваш проект React с помощью React Hooks
    React + Firebase - это мощная комбинация для быстрого и безопасного создания приложений, от проверки концепции до массового производства. Раньше (знаете, несколько месяцев назад) добавление..

    Создайте API с помощью Python FastAPI
    Создание API с помощью Python становится очень простым при использовании пакета FastAPI. После установки и импорта вы можете создать приложение FastAPI и указать несколько конечных точек. Каждой..

    Веселье с прокси-сервером JavaScript
    Прокси-серверы JavaScript — это чистый сахар, если вы хотите создать некоторую общую логику в своих приложениях, чтобы облегчить себе жизнь. Вот один пример: Связь клиент-сервер Мы..

    Получить бесплатный хостинг для разработчиков | Разместите свой сайт за несколько шагов 🔥
    Статические веб-сайты — это веб-страницы с фиксированным содержанием и его постоянным содержанием. Но теперь статические сайты также обрабатывают динамические данные с помощью API и запросов...