На странице 88 книги Стивена Toub вStreaming данных
http://www.microsoft.com/download/en/details.aspx?id=19222
Существует код
private BlockingCollection<T> _streamingData = new BlockingCollection<T>();
// Parallel.ForEach
Parallel.ForEach(_streamingData.GetConsumingEnumerable(),
item => Process(item));
// PLINQ
var q = from item in _streamingData.GetConsumingEnumerable().AsParallel()
...
select item;
Стивен затем упоминает
«, когда передавая результат вызова GetConsumingEnumerable как источник данных для Parallel.ForEach, потоки u sed цикл может быть заблокирован, когда коллекция становится пустой. И заблокированный поток не может быть выпущен Parallel.ForEach обратно в ThreadPool для выхода на пенсию или других целей. Таким образом, с кодом, как показано выше, если есть какие-то периоды времени, когда эта коллекция пуста, количество нитей в процессе, может постоянно расти;»
Я не понимаю, почему число потоков будет расти?
Если коллекция пуста, то не бы BlockingCollection не запрашивать какие-либо дополнительные темы?
Следовательно, вы не должны делать WithDegreeOfParallelism ограничить количество используемых потоков на BlockingCollection
Но почему бы вам насытить процессор при блокировке? – TheWommies
Пример: Современные твердотельные накопители имеют несколько внутренних путей ввода-вывода. Mine имеет 4. Когда у вас есть 2 ядра, вам по-прежнему нужно 4 потока, чтобы насытить ваш SSD. Алгоритм пула потоков фактически попытался бы создать 4 потока (по крайней мере, если бы он работал правильно). Он будет создавать нити до тех пор, пока не будут созданы 5. Тогда, было бы замечательно, что пятый не увеличил пропускную способность, поэтому он удалил бы пятый поток. – usr
Детали этого процесса не документированы. Но я часто видел это на практике, когда мои задачи выполняли IO. – usr