答案是,它是整个并行操作的上限,与核心数量无关。
所以,即使你不使用CPU,因为你正在等待IO或锁,没有额外的任务将并行运行,只有你指定的最大值。
为了找到答案,我写了这段测试代码。在那里有一个人造锁以刺激TPL使用更多的线程。代码等待IO或数据库时也会发生同样的情况。
class Program
{
static void Main(string[] args)
{
var locker = new Object();
int count = 0;
Parallel.For
(0
, 1000
, new ParallelOptions { MaxDegreeOfParallelism = 2 }
, (i) =>
{
Interlocked.Increment(ref count);
lock (locker)
{
Console.WriteLine("Number of active threads:" + count);
Thread.Sleep(10);
}
Interlocked.Decrement(ref count);
}
);
}
}
如果我没有指定MaxDegreeOfParallelism,则控制台日志记录显示最多可同时运行大约8个任务。像这样:
Number of active threads:6
Number of active threads:7
Number of active threads:7
Number of active threads:7
Number of active threads:7
Number of active threads:7
Number of active threads:6
Number of active threads:7
Number of active threads:7
Number of active threads:7
Number of active threads:7
Number of active threads:7
Number of active threads:7
Number of active threads:7
Number of active threads:7
Number of active threads:7
Number of active threads:7
Number of active threads:7
Number of active threads:7
它开始降低,随着时间的推移而增加,最终试图同时运行8次。
如果我把它限制在某些任意值(比如2),我得到
Number of active threads:2
Number of active threads:1
Number of active threads:2
Number of active threads:2
Number of active threads:2
Number of active threads:2
Number of active threads:2
Number of active threads:2
Number of active threads:2
Number of active threads:2
Number of active threads:2
Number of active threads:2
Number of active threads:2
Number of active threads:2
Number of active threads:2
Number of active threads:2
Number of active threads:2
哦,这是一个四核机器上。
我的逻辑没有任何等待或任何IO,它只是更新SQL,是的SQL可能有自己的,但大多数我正在等待SQL完成。什么是使用的活动线程的默认最大数量? – 2012-03-02 19:49:19
默认值是每个核心2个,但如果您的代码不使用CPU,则TPL可以提高此值。大多数数据库涉及一定数量的IO。 – 2012-03-02 20:01:08
如果我的6核机器负载很重,它只使用1或2个线程。如果其轻载,则会达到12.它的智能足以将现有的系统负载考虑在内。 – Contango 2013-08-08 14:05:21