Während ich Parallel.ForEach in meinem Programm verwendete, stellte ich fest, dass einige Threads nie zu Ende schienen. Tatsächlich brachte es immer neue Fäden hervor, ein Verhalten, das ich nicht erwartet hatte und definitiv nicht möchte. die, genau wie mein ‚echtes‘ ProgrammParallel.ForEach erzeugt immer neue Threads
konnte ich dieses Verhalten mit dem folgenden Code reproduzieren, sowohl Prozessor und Speicher verwendet eine Menge (.NET 4.0-Code):
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;
var jobs = Enumerable.Range(0, 2000);
Parallel.ForEach(jobs, delegate(int jobNr)
{
Interlocked.Increment(ref concurrentThreads);
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++)
{
current = new Node(current);
nodes.Add(current);
}
TimeSpan elapsed = DateTime.Now - startMoment;
int threadsRemaining = Interlocked.Decrement(ref concurrentThreads);
Console.WriteLine("[{0:mm\\:ss}] Job {1,4} complete. {2} threads remaining.", elapsed, jobNr, threadsRemaining);
});
}
}
Wenn lief auf meinem Quad-Core, es beginnt zunächst mit 4 gleichzeitigen Threads, wie Sie es erwarten würden. Mit der Zeit werden jedoch immer mehr Threads erstellt. Schließlich wirft das Programm dann eine OutOfMemoryException:
[00:00] Job 0 complete. 3 threads remaining.
[00:01] Job 1 complete. 4 threads remaining.
[00:01] Job 2 complete. 4 threads remaining.
[00:02] Job 3 complete. 4 threads remaining.
[00:05] Job 9 complete. 5 threads remaining.
[00:05] Job 4 complete. 5 threads remaining.
[00:05] Job 5 complete. 5 threads remaining.
[00:05] Job 10 complete. 5 threads remaining.
[00:08] Job 11 complete. 5 threads remaining.
[00:08] Job 6 complete. 5 threads remaining.
...
[00:55] Job 67 complete. 7 threads remaining.
[00:56] Job 81 complete. 8 threads remaining.
...
[01:54] Job 107 complete. 11 threads remaining.
[02:00] Job 121 complete. 12 threads remaining.
..
[02:55] Job 115 complete. 19 threads remaining.
[03:02] Job 166 complete. 21 threads remaining.
...
[03:41] Job 113 complete. 28 threads remaining.
<OutOfMemoryException>
Das Diagramm zur Speicherauslastung für das Experiment oben ist wie folgt:
(Der Screenshot in Niederländisch ist, der obere Teil repräsentiert Prozessor Verwendung, die untere Teilspeicherverwendung) Wie Sie sehen können, sieht es so aus, als ob ein neuer Thread fast jedes Mal erzeugt wird, wenn der Garbage Collector in den Weg kommt (wie man an den Einbrüchen der Speichernutzung sehen kann).
Kann mir jemand erklären, warum das passiert und was ich dagegen tun kann? Ich will nur .NET Laichen neue Themen zu stoppen, und beenden Sie die vorhandenen Threads zuerst ...
ich eine Follow-up-Frage shooted habe [ ] (http://stackoverflow.com/questions/15381174/how-to-count-the-amount-of-concurrent-threads-in-net-application) Wenn Sie die Threads direkt c cotieren, erhöhen sie sich meist nur (sehr selten und unwesentlich abnehmend) – Fulproof