170 похожих чатов

Вопрос: вызов await блокирует поток? Я понимаю, что такой код:


var result = await DoWorkAsync();
Console.WriteLine(result);
разворачивается компиляторов в

var awaiter = DoWorkAsync();
awaiter.OnCompleted(() =>
var result1 = awaiter.GetResult();
Console.WriteLine(result);
)
Получается допустим работают два потока: основной и поток из тредпула
Основной доходит до вызова функции, заходит в DoWorkAsync(), и почти моментально оттуда выходит и может дальше работать.
На этом этапе DoWorkAsync() начинает исполнять поток из тредпула.
Основной поток ожидает признак продолжения, для того, чтобы выполнить операторы дальше.

Вот тут не понятно: основной поток ждет - означает ли это то, что он заблокирован? Или там под капотом как-то хитро устроено, что поток живой, но просто курит, пока поток из пула не скажет, мол я закончил работу - продолжай

4 ответов

10 просмотров

Все треды свободны, если у тебя по-настоящему асинхронная работа с IO, а не только вычисления. https://blog.stephencleary.com/2013/11/there-is-no-thread.html

Mikhail-Izmailov Автор вопроса
Ilya L
Все треды свободны, если у тебя по-настоящему асин...

Я читаю вот его книгу как раз Что означает асинхронная IO ? Подключение к базе данных это IO. Как я понимаю, асинхронность в этом случае заключается в том, что поток, который инициирует подключение - возвращается в тредпул на то время, пока БД не подключится, если не применять ConfigureAwait(false);

Для начала нужно понять, что такое стейт машина. Самая простая стейт машина это IEnumerator<T> Это просто метод MoveNext() и свойство Current. Теперь самое интересное - пишем цикл foreach, который работает с этим интерфейсом под капотом. Для пользователя это интерфейс IEnumerable<T>, но он сразу возвращает IEnumerator<T>, и дальше работа идет только с этим интерфейсом. Посмотрите этот интерфейс, и попробуйте понять, что именно компилятор делает. Посмотрите il, который генерится. Попробуйте реализовать свой IEnumerator<T> с помощью yield return, а потом попробуйте написать ручками тот же самый код. Получится, что вам прийдется сохранить состояние, и использовать в методе MoveNext() оператор switch case, который будет это состояние использовать. То есть код foreach метода на самом деле разбивается на куски, которые вызываются по отдельности в рамках отдельных клауз switch case, в зависимости от состояния. С async/await происходит подобная история - async await это всего лишь синтаксический сахар к стейт машине. То есть, не просто генерится код, который тут же выходит - вызывающий метод это тоже стейтмашина. И кто-то должен вызывать метод MoveNext() много раз подряд. В промежутках между этими вызовами никакого потока нет. Этот “кто-то”, который вызывает ваш код снова и снова происходит во взятом из тредпула треде. По сути можно считать, что это каждый раз новый тред, хотя это на самом деле просто спящие треды переиспользуются из тредпула. А пробуждает этот тред прерывание, которое зарегистрировано в каком-либо драйвере. То есть, в промежутке нет никакого потока.

George Polevoy
Для начала нужно понять, что такое стейт машина. ...

То есть, ваш пример кода валидный, но он не вполне объясняет, что происходит. Следует понимать, что он находится в рамках клаузы case внутри switch, и за один вход в метод MoveNext выполняется только одна клауза, потом следует return. ``` MoveNext() { switch (this._state) { case START: var awaiter = DoWorkAsync(); this._state = WORK_STARTED; break; case WORK_STARTED: var result1 = awaiter.GetResult(); Console.WriteLine(result); break; } } ```

Похожие вопросы

Обсуждают сегодня

я не магистр хаскеля, но разве не может лейзи тип конвертнуться в не-лейзи запросив вычисление содержимого прям при инициализации?
deadgnom32 λ madao
47
читать файл максимально быстро? странный вопрос))
zamtmn
53
How to create an OS in C? what to study?
Linus
18
Привет, кто может сделать юзербота с апи? Задачи: - создавать группы - создавать каналы - задавать для созданных каналов аватарку или эмоджи, имя группы - добавлять в группы...
Lencore
11
тоесть, указав return eax, сгенерируется никому ненужная инструкция mov eax,eax ?
Aiwan \ (•◡•) / _bot
24
Компания Elif ищет менеджера проектов, который будет заниматься поиском и ведением новых проектов. Прежде чем приступить к работе, вам нужно пройти наш недельный курс, где вы ...
Elif
2
@HemulGM Параметры у AddStream поменялись? Несостыковка какая-то
Катерина Свиридова
12
Подскажите, есть какие-то события создания/уничтожения у TFrame по типу TForm (OnCreate и OnClose/OnDestroy) ? Как отловить создание TFrame и "перед" уничтожением. На Tframe р...
Денис
8
а чем хуже?
Alexey Kulakov
10
Компания Elif ищет менеджера проектов, который будет заниматься поиском и ведением новых проектов. Прежде чем приступить к работе, вам нужно пройти наш недельный курс, где вы ...
Elif
1
Карта сайта