2013-03-13 68 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

相關問題