Siehe folgende gleichzeitige Leistungsanalyse, welche die durch eine parallele foreach geleisteten Arbeit:Warum habe ich hier ein Schloss?
Innerhalb der Schleife jeder Thread Daten aus der DB liest und sie verarbeiten. Zwischen den Threads gibt es keine Sperren, da sie jeweils unterschiedliche Daten verarbeiten.
Sieht aus, als gäbe es in allen Threads der foreach aus unbekannten Gründen periodische Sperren (siehe die schwarzen vertikalen Rechtecke). Wenn Sie das ausgewählte gesperrte Segment (das dunkelrote) sehen, sehen Sie, dass der Stapel den im StockModel.Quotation-Konstruktor gesperrten Thread anzeigt. Der Code dort erstellt nur zwei leere Listen!
Ich habe irgendwo gelesen, dass dies durch die GC verursacht werden könnte, so habe ich die Garbage Collection geändert mit im Server-Modus ausgeführt wird:
<runtime>
<gcServer enabled="true"/>
</runtime>
Ich habe eine kleine Verbesserung (ca. 10% - 15 % schneller), aber ich habe immer noch die vertikalen Sperren.
Ich habe auch alle DB-Abfragen der WITH (NOLOCK) hinzugefügt, da ich nur Daten ohne Unterschied lese.
Irgendwelche Hinweise darauf, was hier passiert?
Der Computer, auf dem die Analyse durchgeführt wurde, hat 8 Kerne.
EDIT: Nach der Aktivierung von Microsoft Symbol-Servern stellt sich heraus, dass alle Threads bei Aufrufen wie wait_gor_gc_done oder WaitUntilGCComplete blockiert sind. Ich dachte, dass GCServer aktivieren ich einen GC für jeden Thread hatte, so würde ich die "vertikale" Sperre vermeiden, aber scheint, dass es nicht der Fall ist. Liege ich falsch? Die zweite Frage: Da die Maschine nicht unter Speicherdruck steht (5 von 8 Gigs werden verwendet) gibt es eine Möglichkeit, die GC-Ausführung zu verzögern oder zu unterbrechen, bis die parallele foreach endet (oder weniger häufig zu feuern))
Wenn Sie eine Menge Objekte zuweisen und die Sperren tatsächlich vom GC verursacht werden, haben Sie versucht, einen GC.Collect zu erzwingen, bevor Sie mit der TPL arbeiten? GC.Collect mit GCCollectionMode.Forced. – Alex
Nun, ich ordne innerhalb der Schleife eine große Menge kleiner Objekte zu, die am Ende jeder Iteration "aufgegeben" werden. Könnte dies die ganze Menge von Threads sperren, wenn sie GC'ed sind? –
Aktivieren Sie den Microsoft Symbol Server, um bessere Stack-Traces zu erhalten. Angesichts der langen Wartezeit sieht das einfach nach einfachen Speicherbereinigungen aus. –