在Parallel.ForEach中指定默认的MaxDegreeOfParallelism?

时间:2014-12-18 01:59:05

标签: c# multithreading parallel-processing task-parallel-library

我们希望有选择地控制并行循环中“线程”的数量,以避免压倒Web服务(例如)。

是否可以在MaxDegreeOfParallelism循环中指定自定义Parallel.ForEach,还可以根据需要恢复为默认值?看似零(0)是MaxDegreeOfParallelism的无效值,而我希望它只是意味着“忽略”。

换句话说,你能避免写这种类型的代码吗?

int numParallelOperations = GetNumParallelOperations();
if (numParallelOperations > 0)
{
 ParallelOptions options = new ParallelOptions();
 options.MaxDegreeOfParallelism = numParallelOperations;
 Parallel.ForEach(items, options, i => 
 {
   Foo(i);
 });
}
else
{ 
 Parallel.ForEach(items, i => 
 { 
   Foo(i);
 });
}

2 个答案:

答案 0 :(得分:5)

您的意思是-1MSDN

  

MaxDegreeOfParallelism限制并发操作的数量   通过此ParallelOptions传递的并行方法调用运行   实例到设定值,如果是正数。如果   MaxDegreeOfParallelism是-1,那么就没有限制了   并发运行的数量。

您可以像这样控制近似线程数:

// use only (ca) one kernel:
int degreeOfParallelism = 1;
// leave (ca) one kernel idle:
int degreeOfParallelism = Environment.ProcessorCount - 1;
// use (ca) half of the kernels:
int degreeOfParallelism = Environment.ProcessorCount > 1 ? 
                          Environment.ProcessorCount / 2 : 1;
// run at full speed:
int degreeOfParallelism =  - 1;

var options = new ParallelOptions();
options.MaxDegreeOfParallelism = degreeOfParallelism;

Parallel.For(0, x, options, y => 
//...

答案 1 :(得分:2)

这可能不是一个明确的答案,因为我只是加入StackOverflow而无法添加评论。我不相信有可能按照你的要求去做,但我知道MSDN文档声明-1是参数,它设置了无限数量的任务来运行ForEach。根据我的经验,最好离开CLR以确定将运行多少并发任务,除非您真的知道自己在做什么。并行库是高级的,如果你需要真正做这样的事情,你应该在较低级别编码并控制自己的线程,而不是将它留给TaskScheduler或ThreadPool等,但这需要大量的实验让你自己的算法有效运行。 我唯一可以建议的是包装Parallel.ForEach方法以包含ParallelOptions.MaxDegreeOfParallism的设置,以减少重复的代码,并使您能够添加接口并以同步方式测试异步代码。 抱歉没有提供更积极的回应!