Re[5]: async прерывание треда
От: VladD2 Российская Империя www.nemerle.org
Дата: 02.09.21 17:29
Оценка:
Здравствуйте, Ночной Смотрящий, Вы писали:

НС>В Core оно так не работает.


С коркой почти не работал. А как же там? Нет ThreadAbortException?

НС>В старом ASP.NET, который в FW, контекст синхронизации не создает потоки, весь асинхронный код в рамках одного запроса выполняется в одном потоке. Причем, в отличие от винформсов, там еще и message loop с пробросом коллбеков через него отсутствует.


Потоки должны создавать те методы, что таски возвращают. Скажем если вызвать Delay, то он создаст таймер, а тот сработав создаст продолжение на потоке из пула.

НС>В ASP.NET Core контекст синхронизации дефолтный, т.е. использует для асинхронных операций потоки из пула.


Так это про продолжение. У него же проблема прямо в исходном потоке. Походу у него корка.
Погуглил там походу через Pipe чтение идет.
https://github.com/dotnet/corefx/blob/master/src/System.IO.Pipelines/src/System/IO/Pipelines/Pipe.DefaultPipeReader.cs

НС>Не обязательно. Все зависит от контекста синхронизации.


Контекст работает при продолжении. А вот сам метод должен как-то асинхронность реализовать. Delay использует таймер и потоки из пула. Yield в зависимости от условий ставит задачу в очередь или что-то там делает. А в его случае используется ReadAsync из PipeReader-а, который в итоге ReadAsync на пайпе вызывает. Поток срубают когда вызов в его кишках находится.

Собственно ему уже помогло явный запуск задачи.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[4]: async прерывание треда
От: Sharov Россия  
Дата: 02.09.21 18:12
Оценка:
Здравствуйте, VladD2, Вы писали:


S>>Это почему? Из-за void (async void)?

VD>Бай дизайн. Ключевое свойство async ни хрена не приводит к асинхронности (переводу выполнения на другой поток). Запуск потока где–то должен случиться явно. Даже await–вызовы начинаются синхронно и уже внутри тем или иным методом инициируют асинхронность.

Скажем так, async гарантия того, что rt будет пытаться запустить соотв. фрагмент кода в каком-нибудь потоке, т.е.
будет запущена машинерия выбора потока. Что не отменяет того факта, что фрагмент кода будет запущен в том же потоке,
т.е. синхронно. Под асинхронностью я называю "запуск выбора потока для задачи". И в данном случае задача вполне аснхрнна.


S>>Что значит "рубят на физическом уровне"?


VD>Когда поток срубается дотнетом, в нем эмулируется исключение ThreadAbortException. Но есши потгк создан и контролируется анменеджед–кодом он может быть срублен вызовом TerminateThread. При этом эмулировать генерацию ThreadAbortException будет некому и отряд просто не заметит потери бойца.


Но это не наш случай. Никакого "рубят на физическом уровне" тут быть не должно.


S>>Так есть же в цикле readResult = await bodyReader.ReadAsync();

VD>Откровенно говоря не заметил await в первый раз. Подсветка подвела.
VD>Очевидно он начинается на исходном потоке или блокирует его. Плюс там возможен захват контекста и попытка продолжиться на нем же (предположение).

Ничего он его не блокирует, а возвращает в пул потоков.


VD>Все эти async–и в дотнете сделаны кривовато. Слишком много не явного (не явные глобальные переменные контекста, не внятная семантика асинхронности).


Соглашусь -- мне они нелегко даются + куча возможностей себе отстрелить что-нибудь. С др. стороны НС
когда неплохо объяснил, что это всего лишь навсего нарезка кода на всяческие promis'ы с поддержкой компилятора.

VD>Люди свято верят, если метод async, то код уже в другом потоке. Но это не так. Где–то асинхронность должна инициироватся явно. А то, что метод с async это делает, не более чем соглашение. Это надо держать в уме.


Выше я уже ответил, что понимаю под асинхронностью.
Кодом людям нужно помогать!
Re[7]: async прерывание треда
От: Sharov Россия  
Дата: 02.09.21 18:28
Оценка:
Здравствуйте, Serginio1, Вы писали:

https://www.youtube.com/watch?v=eip2Xjrzp9g -- вот тут парень 2ч на пальцах все объясняет.
Отличная лекция.
Кодом людям нужно помогать!
Re[5]: async прерывание треда
От: VladD2 Российская Империя www.nemerle.org
Дата: 02.09.21 21:37
Оценка: +1
Здравствуйте, Sharov, Вы писали:

S>Скажем так, async гарантия того, что rt будет пытаться запустить соотв. фрагмент кода в каком-нибудь потоке, т.е.


Это как раз главная ошибка все кто пытается использовать async. Правда в том, что async — это тупой конечный автомат, который всегда запускает асинхронный метод в том же потоке, что и содержит await. А вот что будет делать вызванный метод — это зависит от его реализации. Так же не ясно где будет продолжаться вызывающий метод, так как async тупо переключает лишь автомат, а поток на котором будет продолжение зависит от авэйтера и контекста.

Потому мне эти async-ки и не нравятся. Уж больно не понятно для людей что в реальности происходит. Лучше уж явно ими управлять. А еще лучше использовать подход акторов, когда все коммуникации между потоками происходят через очереди сообщений.

S>будет запущена машинерия выбора потока.


Что за невиданная зверушка эта твоя "машинерия выбора потока"?

S>Но это не наш случай. Никакого "рубят на физическом уровне" тут быть не должно.


Это почему? Я с вебом особо не работаю, но почему бы потоку не быть запущенным веб сервером написанному на плюсах?

В прочем, эти долбанные async и исключения могут потерять. Там много чего не продумано.

S>Ничего он его не блокирует, а возвращает в пул потоков.


Это кто тебе сказал? Там под капотом (я поглядел) Pipe.ReadAsync вызывается. Он может спокойно блокироваться. Вообще, это еще одно заблуждение, что эти долбанные ReadAsync реально всегда асинхронные. Попробуй читать/писать в разны потоках и поймешь, что это не так. А вот если явно стартануть новый поток (взять из пула), то асинхронность гарантирована.

S>Соглашусь -- мне они нелегко даются + куча возможностей себе отстрелить что-нибудь. С др. стороны НС

S>когда неплохо объяснил, что это всего лишь навсего нарезка кода на всяческие promis'ы с поддержкой компилятора.

Ну, вот все это сделано не системно и слишком много неявного. Я ради развлечения реализовывал многопоточность разными методами и пришел к тому, что лучший вариант — это очереди сообщений и модель акторов (когда экземпляр класса разгребает свою очередь и отвечает путем посылки асинхронных сообщений в другие очереди. При этом ты просто забываешь о потоках и мыслишь в терминах посылки сообщений. Там тоже есть вои нюансы, но ошибки выявлятся элементарно, в отличии от прямой работы с потоками и блокировками и тем более async-ами. Вот их мало кто до конца понимает. Вроде смотришь в код и он очевиден, но не фига это не так.

S>Выше я уже ответил, что понимаю под асинхронностью.


Ну, вот в том-то и проблема, что ты тоже до конца эту модель не понимаешь. А лично я и не хочу ее понимать. Время можно проводить интереснее.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[6]: async прерывание треда
От: Sharov Россия  
Дата: 03.09.21 00:04
Оценка:
Здравствуйте, VladD2, Вы писали:

VD>Здравствуйте, Sharov, Вы писали:


S>>Скажем так, async гарантия того, что rt будет пытаться запустить соотв. фрагмент кода в каком-нибудь потоке, т.е.

VD>Это как раз главная ошибка все кто пытается использовать async. Правда в том, что async — это тупой конечный автомат, который всегда запускает асинхронный метод в том же потоке, что и содержит await. А вот что будет делать вызванный метод — это зависит от его реализации. Так же не ясно где будет продолжаться вызывающий метод, так как async тупо переключает лишь автомат, а поток на котором будет продолжение зависит от авэйтера и контекста.

Дал маху, проверил -- компилятор предупреждает, что async без await будет синхронным. Думал, что метод
вообще не скомпилируется. Короче, без await "машинерия выбора потока" не будет работать. Собственно, это
и есть нарезка на промисы.

VD>Потому мне эти async-ки и не нравятся. Уж больно не понятно для людей что в реальности происходит. Лучше уж явно ими управлять. А еще лучше использовать подход акторов, когда все коммуникации между потоками происходят через очереди сообщений.


Как и везде, нужно время чтобы привыкнуть и приноровиться.

S>>будет запущена машинерия выбора потока.

VD>Что за невиданная зверушка эта твоя "машинерия выбора потока"?

КА.

S>>Но это не наш случай. Никакого "рубят на физическом уровне" тут быть не должно.

VD>Это почему? Я с вебом особо не работаю, но почему бы потоку не быть запущенным веб сервером написанному на плюсах?

Ну потому что это будет работать под IIS, который, вроде сам unmanaged, но будет хостить managed host.
Следовательно, все потоки будут managed.

VD>В прочем, эти долбанные async и исключения могут потерять. Там много чего не продумано.


Не могут, кроме случаев с async void (выше писали).

S>>Ничего он его не блокирует, а возвращает в пул потоков.

VD>Это кто тебе сказал? Там под капотом (я поглядел) Pipe.ReadAsync вызывается. Он может спокойно блокироваться. Вообще, это еще одно заблуждение, что эти долбанные ReadAsync реально всегда асинхронные. Попробуй читать/писать в разны потоках и поймешь, что это не так. А вот если явно стартануть новый поток (взять из пула), то асинхронность гарантирована.

Вызывающий поток блокируется? Где на код можно глянуть?

VD>Ну, вот в том-то и проблема, что ты тоже до конца эту модель не понимаешь. А лично я и не хочу ее понимать. Время можно проводить интереснее.


Сейчас без этого понимания работу с улицы едва найдешь.
Кодом людям нужно помогать!
Re[6]: async прерывание треда
От: Ночной Смотрящий Россия  
Дата: 03.09.21 04:30
Оценка:
Здравствуйте, VladD2, Вы писали:

НС>>В Core оно так не работает.

VD>С коркой почти не работал. А как же там? Нет ThreadAbortException?

Есть. Но Thread.Abort кидает PlatformNotSupportedException.

VD>Потоки должны создавать те методы, что таски возвращают.


Совсем не обязательно. Continuation для любого таска дефолтный скедулер вызывает через контекст синхронизации. Дефолтный контекст при этом сам порождает потоки, винформсный прокидывает вызов через message loop, а вот старый аспнет выполняет в том же потоке, поэтому если там какая то блокировка — привет, дедлок.
А еще есть Task.Run, который сам берет потоки из пула, вне зависимости от контекста.
... << RSDN@Home 1.3.17 alpha 5 rev. 62>>
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.