c#Process.GetCurrentProcess()。Threads.Count在使用MaxDegreeOfParallelism时没有返回预期值?

时间:2014-11-11 17:34:29

标签: c# multithreading

我正在做这样的事情......

Task.Factory.StartNew(() =>{ 
    Parallel.ForEach(list, new ParallelOptions { MaxDegreeOfParallelism = 10 }, (listitem, state) =>
    {
        //do stuff here
        Console.writeln(Process.GetCurrentProcess().Threads.Count);               
    });
});

线程数是我的应用程序总是超过10?限制我的应用程序使用的线程数我做错了什么?

2 个答案:

答案 0 :(得分:3)

根据MSDN

  

默认情况下,For和ForEach将使用底层调度程序提供的许多线程,因此从默认值更改MaxDegreeOfParallelism只会限制将使用多少并发任务。

因此,线程数将超过10,但这些线程中不会有超过10个一次运行。这为底层框架节省了必须跟踪每个线程并向其附加代码的麻烦,如果另一个错误可能会破坏一个操作的稳定性。相反,我们发现它可以制造任意多个线程并限制一次可以运行多少线程。

你甚至可以通过在课堂上添加一个Count来测试它,看看它有多高:

// In the class scope
int _count = 0;
int MaxCount = 0;
object key = new object();

int Count
{
    get { lock(key) return _count; }
    set
    {
        lock(key)
        {
            _count = value;
            if(_count > MaxCount) MaxCount = value;
        }
    }
}
...
Task.Factory.StartNew(() =>{ 
    Parallel.ForEach(list, new ParallelOptions { MaxDegreeOfParallelism = 10 }, (listitem, state) =>
    {
        Count++;
        Console.writeln(Process.GetCurrentProcess().Threads.Count);
        Count--;            
    });
});

答案 1 :(得分:3)

MaxDegreeOfParallelism不限制进程的线程数(例如,您的控制台应用程序)。它限制了您尝试在Parallel.ForEach

内并行运行的操作的线程数

同时您的应用程序可以并行运行x个额外的线程,Process.GetCurrentProcess().Threads.Count将它们全部计算在内。