Любопытно, почему бы не использовать TPL в .NET 4.0?
http://msdn.microsoft.com/en-us/library/dd537609.aspx
Существует превосходный технический документ, который учитывается при разработке TPL. Если вы не можете использовать .NET 4, вам следует взглянуть на этот документ и рассмотреть некоторые из полученных ошибок.
Обновлено на основе комментариев, указывающих на очевидное.
Я бы использовал синтаксический сахар, как,
ForEach<Tsource>(Predicate<IEnumerable<TSource>> isParallel, IEnumerable<TSource> source, Action<TSource> body)
{
if(isParallel(source))
{
Parallel.ForEach<TSource>(source, body);
}
else
{
foreach (TSource element in source)
{
body(element);
}
}
}
У вашей реализации есть два основных преимущества.
- Вы перечисляете два раза, один раз, чтобы добавить элементы для зацикливания, и второй раз во время выполнения.
- Это не сразу очевидно, но вы останавливаете Parallel.ForEach и не можете использовать самый эффективный метод получения. Parallel.ForeEach не всегда будет использовать GetEnumerator в IEnumerable. Конструктор перечислителя не является параллельным, если ваш элемент реализует IList, Parallel.ForEach будет использовать индексатор, чтобы позволить каждому потоку обращаться к элементу в источнике, не дожидаясь, пока перечислитель выполнит итерацию по списку. ConcurrentBag не реализует IList.
Это бумага, о которой я говорил, http://www.microsoft.com/download/en/details.aspx?displaylang=en&id=19222.
Это все очень хорошо читается, если вы воплощаете это, но обратите особое внимание,
Страницы 1 [5-7], 26, 3 [0-2].
Синтаксический сахар означает, что вы можете называть его как с TPL,
MyParllelLibrary.ForEach( (list) => true, list), item =>
{
// What my code does
});