Как ведут себя потоки портов завершения пула потоков во время асинхронного ввода-вывода в .NET / .NET Core? - PullRequest
1 голос
/ 23 сентября 2019

. Внутренний пул потоков .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).

...