RD>>Доходит до semaphore.Wait() и встает в состояние WaitSleepJoin.
A>Я о случае когда задач на обработку нет и в semaphore.Wait не вызывается.
A>Т.е. все созданные задачи через StartNew завершились и в очереди нет новых задач. Логично же предположить, что сработает механизм "сборки" долговременно не активных потоков.
Так и есть. Если случился переизбыток потоков, то ThreadPool подчищает лишние (по крайней мере в .NET 4 и старше).
Но для этого поток должен быть неактивен (Suspended).
А в твоем случае каждый из 50-100 потоков по циклу либо процесит очередной work item (Running), либо ждет на семафоре (WaitSleepJoin).
Ну либо я не вполне уловил детали твоей реализации