Два вида нитей - использующие проц и ввод-вывод

Я не понял, как сделать так, чтобы CPU-bound поток не блокировался на вводе-выводе.

«когда некий поток уходит в ожидание, он исчезает из планирования и наше приложение меньше задействует процессор, т.к. с точки зрения только CPU-bound операций мы теряем поток исполнения.»

«ожидание от оборудования происходит в потоке, который инициировал это ожидание. Т.е. если мы будем ожидать в пуле потоков, мы снизим его уровень параллелизма. Как это решить? Инженеры из Microsoft создали для этих целей внутри ThreadPool второй пул: пул ожидающих потоков. И когда некий код, работающий в основном пуле решается встать в блокировку, сделать он это должен не тут же, в основном пуле, а специальным образом: перепланировавшись на второй пул»
«это значит, что в делегате, работающем в ThreadPool вставать блокировку нельзя. Он для этого не предназначен. Вместо этого необходимо использовать следующий код»

ThreadPool.RegisterWaitForSingleObject

«Операция ожидания выполняется потоком из пула потоков.»

В официальной документации никаких таких уточнений, про то, что используется “пул ожидающих потоков” я не вижу.

Разъясните, пожалуйста, как надо.

Ещё эта фраза “пул ожидающих потоков” используется в переводах на rsdn:

«часто упорядоченность потоков, присущая очередям, не нужна в Wait/Pulse-приложениях, и в таких случаях проще представить себе некий “пул” ожидающих потоков. Каждый Pulse освобождает один поток из пула.»

Я тоже не слышал о таком пуле. И тут написано, что не надо использовать пул если надо надолго блокировать The managed thread pool - .NET | Microsoft Learn

А это да, звучит правильнее. Про wait thread можно найти и в документации RegisterWaitForSingleObject, и в гугле.
c# - Does ThreadPool.RegisterWaitForSingleObject block the current thread or a thread-pool thread? - Stack Overflow