方法: スレッド ローカル変数を持つ Parallel.ForEach ループを記述する
スレッド ローカル変数を持つ ForEach メソッドを記述する方法を次の例に示します。 ForEach ループが実行されると、そのソース コレクションが複数のパーティションに分割されます。 各パーティションには、"スレッド ローカル" 変数が個別にコピーされます ("スレッド ローカル" という用語は少し不正確です。1 つのスレッド上で 2 つのパーティションが実行されることがあるからです)。
この例のコードおよびパラメーターは、対応する For メソッドによく似ています。 詳細については、「方法: スレッド ローカル変数を持つ Parallel.For ループを記述する」を参照してください。
使用例
ForEach ループでスレッド ローカル変数を使用するには、2 つの type パラメーターを受け取る形式のメソッドを使用する必要があります。 最初のパラメーターではソース要素の型を指定し、2 番目のパラメーターではスレッド ローカル変数の型を指定します。
最初の入力パラメーターはデータ ソースで、2 番目の入力パラメーターはスレッド ローカル変数を初期化する関数です。 3 番目の入力パラメーターは、反復処理ごとに平行ループで呼び出される Func<T1, T2, T3, TResult> です。 プログラマはデリゲートのコードを作成します。入力パラメーターはループから渡されます。 入力パラメーターは、現在の要素、ループの状態のチェックに使用できる ParallelLoopState 変数、およびスレッド ローカル変数です。 プログラマはスレッド ローカル変数を返します。メソッドは、そのスレッド ローカル変数をこのパーティションの次の反復処理に渡します。 この変数はすべてのループ パーティションで異なります。
ForEach メソッドの最後の入力パラメーターは、すべてのループが完了したときにメソッドによって呼び出される Action<T> デリゲートです。 メソッドは、このスレッド (ループ パーティション) のスレッド ローカル変数の最終値を返します。プログラマは、その最終値をキャプチャして、このパーティションの結果と他のパーティションの結果を連結するコードを作成します。 デリゲート型は Action<T> であるため、戻り値はありません。
' How to: Write a Parallel.ForEach Loop That Has Thread-Local Variables
Imports System.Threading
Imports System.Threading.Tasks
Module ForEachThreadLocal
Sub Main()
Dim nums() As Integer = Enumerable.Range(0, 1000000).ToArray()
Dim total As Long = 0
' First type paramemter is the type of the source elements
' Second type parameter is the type of the local data (subtotal)
Parallel.ForEach(Of Integer, Long)(nums, Function() 0,
Function(elem, loopState, subtotal)
subtotal += nums(elem)
Return subtotal
End Function,
Sub(finalResult)
Interlocked.Add(total, finalResult)
End Sub)
Console.WriteLine("The result of Parallel.ForEach is {0}", total)
Console.WriteLine("Press any key to exit.")
Console.ReadKey()
End Sub
End Module
namespace ThreadLocalForEach
{
using System;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
class Test
{
static void Main()
{
int[] nums = Enumerable.Range(0, 1000000).ToArray();
long total = 0;
// First type parameter is the type of the source elements
// Second type parameter is the type of the local data (subtotal)
Parallel.ForEach<int, long>(nums, // source collection
() => 0, // method to initialize the local variable
(j, loop, subtotal) => // method invoked by the loop on each iteration
{
subtotal += nums[j]; //modify local variable
return subtotal; // value to be passed to next iteration
},
// Method to be executed when all loops have completed.
// finalResult is the final value of subtotal. supplied by the ForEach method.
(finalResult) => Interlocked.Add(ref total, finalResult)
);
Console.WriteLine("The total from Parallel.ForEach is {0}", total);
Console.WriteLine("Press any key to exit");
Console.ReadKey();
}
}
}
参照
処理手順
方法: スレッド ローカル変数を持つ Parallel.For ループを記述する