Перший - набагато кращий варіант.
Parallel.ForEach, внутрішньо, використовує a Partitioner<T>
для розподілу своєї колекції по робочих предметах. Він не буде виконувати одне завдання на предмет, а скоріше замість цього, щоб зменшити накладні витрати.
У другому варіанті буде заплановано одиницю Task
на предмет у колекції. Хоча результати будуть (майже) однаковими, це призведе до набагато більших витрат, ніж потрібно, особливо для великих колекцій, і призведе до того, що загальний час роботи буде повільнішим.
FYI - Партнером, що використовується, можна керувати, використовуючи відповідні перевантаження Parallel.ForEach , якщо це потрібно. Детальніше дивіться у розділі Спеціальні учасники на MSDN.
Основна відмінність під час виконання - це те, що другий буде діяти асинхронно. Це можна дублювати за допомогою Parallel.ForEach, виконуючи:
Task.Factory.StartNew( () => Parallel.ForEach<Item>(items, item => DoSomething(item)));
Роблячи це, ви все-таки скористаєтеся партнерами, але не блокуйте, поки операція не буде завершена.