. Внутренний пул потоков .NET / .NET использует две разные категории потоков: рабочие потоки и потоки IOCP.Оба являются просто обычными управляемыми потоками, но используются для разных целей.С помощью различных API (например, Task.Start
или ThreadPool.QueueUserWorkItem
) я могу запускать асинхронные операции, связанные с ЦП, в рабочих потоках (которые не должны блокироваться, иначе пул потоков, вероятно, создаст дополнительные рабочие потоки).
Но как насчет выполнения асинхронных операций, связанных с вводом / выводом?Как потоки IOCP ведут себя именно в этих ситуациях?В частности, у меня есть следующие вопросы:
- Если я запускаю операцию асинхронного ввода-вывода (например, для файла, канала или сети), я подозреваю, что текущий поток отправляет асинхронный запрос.Я также знаю (через книгу "CLR via C #"), что CLR регистрируется на порту завершения ввода / вывода, который используется для выполнения перекрывающихся асинхронных операций ввода / вывода.Я подозреваю, что этот IOCP связан с асинхронной операцией, поэтому он может поставить в очередь результат асинхронной операции в пул потоков позже. Таким образом, верно ли мое предположение, что поток IOCP не затрагивается при запуске асинхронного запроса?
- Я подозреваю, что когда результат операции асинхронного ввода-вывода сообщается через I /О порт завершения CLR, это место, где потоки IOCP вступают в действие.Результат помещается в очередь в пуле потоков, и для его обработки используется поток IOCP.Однако при чтении некоторых веток форума , подобных этой на MSDN , я чувствую, что потоки IOCP фактически используются для отправки запроса, а затем блокируются, пока результат не вернется. Это тот случай?Блокируются ли потоки IOCP, пока операция ввода-вывода обрабатывается противоположной системой?
- Что насчет
async await
и SynchronizationContext
? Обрабатывает ли поток IOCP ответ асинхронного ввода-вывода, а затем, например, ставит в очередь продолжение в потоке пользовательского интерфейса (при условии, что ConfigureAwait(false)
не вызывается)? - Как насчет .NET Core вLinux / MacOS X?Нет портов завершения ввода / вывода - эмулируются ли они каким-либо образом?
Обновление после комментариев Дэмиена и Ханса:
Дэмиен указал на Потрясающий пост Стивена Туба , в котором дается ответ на первые три пункта:
- Операция асинхронного ввода-вывода отправляется вызывающему потоку.Поток IOCP не задействован.
- Следовательно, потоки IOCP не блокируются во время асинхронного ввода-вывода.
- Когда результат возвращается в приложение .NET, поток IOCP заимствуется для пометки задачиполный.Продолжение ставится в очередь к целевому
SynchronizationContext
или пулу потоков.
Ханс указал, что в IOCP есть механизмы, аналогичные в Linux (epoll) и MacOS (kqueue).