並列 foreach によって実行される作業を表す次の同時実行パフォーマンス分析を参照してください。
ループ内では、各スレッドが DB からデータを読み取り、処理します。それぞれが異なるデータを処理するため、スレッド間にロックはありません。
理由は不明ですが、foreach のすべてのスレッドで定期的なロックが発生しているようです (黒い垂直の長方形を参照)。選択されたロックされたセグメント (濃い赤のセグメント) が表示される場合、スタックが StockModel.Quotation コンストラクターでロックされたスレッドを示していることがわかります。そこのコードは、2 つの空のリストを構築するだけです!
これはGCが原因である可能性があることをどこかで読んだので、ガベージコレクションをサーバーモードで実行するように変更しました:
<runtime>
<gcServer enabled="true"/>
</runtime>
少し改善されましたが (約 10% - 15% 速くなりました)、まだどこにでも垂直ロックがあります。
また、違いなしでデータを読み取るだけなので、すべての DB クエリに WITH(NOLOCK) を追加しました。
ここで何が起こっているかについてのヒントはありますか?
分析が行われたコンピューターには 8 つのコアがあります。
編集: Microsoft Symbol サーバーを有効にすると、wait_gor_gc_done や WaitUntilGCComplete などの呼び出しですべてのスレッドがブロックされることが判明しました。GCServer を有効にすると、スレッドごとに 1 つの GC があるため、「垂直」ロックを回避できると思いましたが、そうではないようです。私が間違っている?
2 番目の質問: マシンがメモリに負荷をかけられていない (8 ギガのうち 5 ギガが使用されている) ため、GC の実行を遅らせるか、並列 foreach が終了するまで一時停止する (または実行頻度を下げるように構成する) 方法はありますか?