Подтвердить что ты не робот

.NET 4... Параллельный .ForEach() вопрос

Я понимаю, что новая TPL (параллельная библиотека задач) реализовала Parallel.ForEach() таким образом, что она работает с "выраженным parallelism". Значит, это не гарантирует, что ваши делегаты будут работать в нескольких потоках, но скорее проверяет, имеет ли хост-платформа несколько ядер, и если это правда, только тогда она распределяет работу по ядрам (по существу 1 поток на ядро).

Если хост-система не имеет нескольких ядер (становится все сложнее и сложнее найти такой компьютер), тогда он будет запускать ваш код последовательно, как "обычный" цикл foreach. Довольно классный материал, честно говоря.

Обычно я делал бы что-то вроде следующего, чтобы поместить мою длинную операцию в фоновый поток из ThreadPool:

ThreadPool.QueueUserWorkItem(новый WaitCallback (targetMethod), новый Object2PassIn());

В ситуации, когда главный компьютер имеет только одно ядро, TPL Parallel.ForEach() автоматически помещает вызов в фоновый поток? Или, должен ли я manaully вызывать любые вызовы TPL из фона thead, чтобы, если я выполняю с одного основного компьютера, по крайней мере, эта логика будет отключена от потока диспетчеризации графического интерфейса?

Моя забота заключается в том, что если я оставлю TPL ответственным за все это, я хочу убедиться, что он определяет его как единое ядро, которое по-прежнему выводит код, который внутри цикла Parallel.ForEach() на фоновый поток, например Я бы сделал это, чтобы не блокировать мой графический интерфейс.

Спасибо за любые мысли или советы, которые у вас могут быть...

4b9b3361

Ответ 1

Ваши предположения неверны.
Parallel.For всегда является блокирующим вызовом.

Даже если компьютер имеет несколько ядер, он все равно будет ждать завершения всех потоков до их возврата.

Если вы не хотите замораживать пользовательский интерфейс, вам всегда нужно явно вызвать ThreadPool.

Ответ 2

Благодаря моему опыту с циклами Parallel.ForEach и Parallel.For я заметил, что заказ может быть не в порядке, что вы, возможно, захотите рассмотреть, прежде чем реализовать.

Такой, как базовый для цикла, будет производить:

Продукт 1 Продукт 2 Продукт 3 Продукт 4

И параллельный цикл может создавать, но не всегда:

Продукт 3 Продукт 1 Продукт 2 Продукт 4

Просто имейте в виду парней.

Ответ 3

Я думаю, что если у вас есть точные требования к счету экземпляра/потока, вам нужно сделать это самостоятельно. У меня создалось впечатление, что тип вызовов Parallel.ForEach предназначен для декларативного получения ядер. Я не знаю точно, но у меня есть подозрительное подозрение, что это будет плохой выбор для чего-то, что блокирует ввод-вывод (в качестве примера).

Ответ 4

Хороший вопрос. Я бы предположил, что он все равно породит нить, даже если есть только одно ядро.

Мне нужно было бы запустить тест на одной основной машине. Поскольку у меня его нет, я буду использовать виртуальную машину и установить ее окружение CPU равным 1 и посмотреть, сколько потоков будет возникать в Parallel ForEach.

Вы можете прочитать следующее:

Параллельно ограничивает количество активных потоков