2013-03-13 46 views
3

运行从Parallel.ForEach keeps spawning new threads有一些我的修改为什么递减一个变量会在C#Parallel.ForEach循环中修改另一个变量的递增?

与注释行输出代码:

//threadsRemaining = Interlocked.Decrement(ref concurrentThreads); 

是“显而易见”的,即预期之一:

[00:00] Job 0 complete. 2 threads remaining. unsafeCount=2 
[00:00] Job 1 complete. 1 threads remaining. unsafeCount=1 
[00:00] Job 2 complete. 3 threads remaining. unsafeCount=3 
[00:00] Job 3 complete. 4 threads remaining. unsafeCount=4 
[00:00] Job 4 complete. 5 threads remaining. unsafeCount=5 
[00:00] Job 5 complete. 6 threads remaining. unsafeCount=6 
[00:01] Job 6 complete. 7 threads remaining. unsafeCount=7 
[00:01] Job 8 complete. 8 threads remaining. unsafeCount=8 
[00:01] Job 7 complete. 9 threads remaining. unsafeCount=9 
[00:01] Job 9 complete. 10 threads remaining. unsafeCount=10 

虽然的输出在对上述线进行评价时,相同的代码是:

[00:00] Job 0 complete. 1 threads remaining. unsafeCount=1 
[00:00] Job 1 complete. 0 threads remaining. unsafeCount=0 
[00:00] Job 3 complete. 0 threads remaining. unsafeCount=0 
[00:00] Job 2 complete. 1 threads remaining. unsafeCount=1 
[00:00] Job 4 complete. 1 threads remaining. unsafeCount=1 
[00:00] Job 5 complete. 1 threads remaining. unsafeCount=1 
[00:01] Job 6 complete. 1 threads remaining. unsafeCount=1 
[00:01] Job 8 complete. 1 threads remaining. unsafeCount=1 
[00:01] Job 9 complete. 1 threads remaining. unsafeCount=1 
[00:01] Job 7 complete. 0 threads remaining. unsafeCount=0 

你能解释一下为什么递减一个变量threadsRemainin停止(或阻止)递增另一个unsafeCount

控制台应用程序的代码:

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Threading; 
using System.Threading.Tasks; 

namespace seParallelForEachKeepsSpawningNewThreads 
{ 
    public class Node 
    { 
    public Node Previous { get; private set; } 
    public Node(Node previous) 
    { 
     Previous = previous; 
    } 
    } 
    public class Program 
    { 
    public static void Main(string[] args) 
    { 
     DateTime startMoment = DateTime.Now; 
     int concurrentThreads = 0; 
     int unsafeCount = 0; 

     var jobs = Enumerable.Range(0, 10); 
     ParallelOptions po = new ParallelOptions 
     { 
     MaxDegreeOfParallelism = Environment.ProcessorCount 
     }; 
     Parallel.ForEach(jobs, po, delegate(int jobNr) 
     { 
     int threadsRemaining = Interlocked.Increment(ref concurrentThreads); 
     unsafeCount++; 

     int heavyness = jobNr % 9; 

     //Give the processor and the garbage collector something to do... 
     List<Node> nodes = new List<Node>(); 
     Node current = null; 
     //for (int y = 0; y < 1024 * 1024 * heavyness; y++) 
     for (int y = 0; y < 1024 * 4 * heavyness; y++) 
     { 
      current = new Node(current); 
      nodes.Add(current); 
     } 

     TimeSpan elapsed = DateTime.Now - startMoment; 
//***************** 
     //threadsRemaining = Interlocked.Decrement(ref concurrentThreads); 
     Console.WriteLine("[{0:mm\\:ss}] Job {1} complete. {2} threads remaining. unsafeCount={2}", 
      elapsed, jobNr, threadsRemaining, unsafeCount); 
     }); 
     Console.WriteLine("FINISHED"); 
     Console.ReadLine(); 
    } 
    } 
} 

回答

5

这就是问题所在:

Console.WriteLine(
    "[{0:mm\\:ss}] Job {1} complete. {2} threads remaining. unsafeCount={2}", 
    elapsed, jobNr, threadsRemaining, unsafeCount); 

最后一部分应该是{3},不{2}。您目前只打印两次threadsRemaining ...

+1

dammit,代码I *的一位不是*正在查看;很容易完成,但。 – 2013-03-13 08:24:38

+0

哎呀...谢谢,这很快,可以在6分钟内接受答案 – Fulproof 2013-03-13 08:28:15

相关问题