通常、これは、既にスレッド ローカル データを提供しているParallel.Forのオーバーロードを使用して処理されます。
このオーバーロードにより、初期化とファイナライズのデリゲートを提供できます。これは、スレッド ローカル データのスレッドごとの初期化と、最後に結果を "マージ" するリダクション関数になります (スレッドごとに 1 回実行されます)。 これについては、こちらに詳しく書きました。
基本的なフォームは、次のようなことです。
object sync = new object();
double result = 0;
Parallel.For(0, collection.Count,
// Initialize thread local data:
() => new MyThreadSpecificData(),
// Process each item
(i, pls, currentThreadLocalData) =>
{
// Generate a NEW version of your local state data
MyThreadSpecificData newResults = ProcessItem(collection, i, currentThreadLocalData);
return newResults;
},
// Aggregate results
threadLocalData =>
{
// This requires synchronization, as it happens once per thread,
// but potentially simultaneously
lock(sync)
result += threadLocalData.Results;
});