Megjegyzés
Az oldalhoz való hozzáféréshez engedély szükséges. Megpróbálhat bejelentkezni vagy módosítani a címtárat.
Az oldalhoz való hozzáféréshez engedély szükséges. Megpróbálhatja módosítani a címtárat.
Az alábbi példa bemutatja, hogyan írhat egy partíció-helyi változókat használó ForEach metódust. Amikor egy ForEach ciklus fut, a forrásgyűjteményét több partícióra osztja. Minden partíció saját másolatot készít a partíció helyi változójáról. A partíció-helyi változó hasonlít egy szál-helyi változóhoz, azzal a kivételrel, hogy több partíció is futtatható egyetlen szálon.
A példában szereplő kód és paraméterek szorosan hasonlítanak a megfelelő For metódusra. További információért lásd: Hogyan írjunk Parallel.For ciklust Thread-Local változókkal.
Ha particionálási helyi változót szeretne használni egy ForEach ciklusban, meg kell hívnia az egyik metódus túlterhelését, amely két típusparamétert vesz igénybe. Az első típusparaméter (TSource
) a forráselem típusát adja meg, a második típusparaméter pedig a TLocal
, a partíció helyi változójának típusát adja meg.
Példa
Az alábbi példa a Parallel.ForEach<TSource,TLocal>(IEnumerable<TSource>, Func<TLocal>, Func<TSource,ParallelLoopState,TLocal,TLocal>, Action<TLocal>) túlterhelést hívja meg egy millió elemből álló tömb összegének kiszámításához. Ennek a túlterhelésnek négy paramétere van:
source
, amely az adatforrás. Implementálnia kell IEnumerable<T>. A példánkban szereplő adatforrás a Enumerable.Range metódus által visszaadott egymillió tagúIEnumerable<Int32>
objektum.localInit
, vagy a partíció-helyi változót inicializáló függvény. Ezt a függvényt minden olyan partícióhoz meghívjuk, amelyben a Parallel.ForEach művelet fut. A példánk a partíció-helyi változót nullára inicializálja.body
egy Func<T1,T2,T3,TResult>, amelyet a ciklus minden iterációján a párhuzamos hurok hív meg. AláírásaFunc\<TSource, ParallelLoopState, TLocal, TLocal>
. Ön adja meg a delegált kódot, és a hurok továbbítja a bemeneti paramétereket, amelyek a következők:A IEnumerable<T>aktuális eleme.
Egy ParallelLoopState változó, amelyet a meghatalmazott kódjában használhat a ciklus állapotának vizsgálatához.
A partíció helyi változója.
A meghatalmazott visszaadja a partíció-helyi változót, amelyet a rendszer a ciklus következő iterációjának ad vissza, amely az adott partíción fut. Minden hurokpartíció ennek a változónak egy külön példányát tartja fenn.
A példában a meghatalmazott hozzáadja az egyes egész számok értékét a partíció-helyi változóhoz, amely a partíció egész elemeinek értékeinek futó összegét tartja fenn.
localFinally
egyAction<TLocal>
delegált, amelyet a Parallel.ForEach hív meg, amikor az egyes partíciók ciklusműveletei befejeződtek. A Parallel.ForEach metódus átadja aAction<TLocal>
delegáltnak a partíció helyi változójának végső értékét ehhez a hurokpartícióhoz, és Ön adja meg azt a kódot, amely végrehajtja a szükséges műveletet a partíció eredményének más partíciók eredményeivel való összekapcsolásához. Ezt a delegált függvényt egyszerre több feladat is meghívhatja. Emiatt a példa a Interlocked.Add(Int32, Int32) metódust használja atotal
változóhoz való hozzáférés szinkronizálásához. Mivel a delegált típusa egy Action<T>, nincs visszatérési érték.
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 thread-local variable (partition 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 += j; //modify local variable
return subtotal; // value to be passed to next iteration
},
// Method to be executed when each partition has completed.
// finalResult is the final value of subtotal for a particular partition.
(finalResult) => Interlocked.Add(ref total, finalResult));
Console.WriteLine($"The total from Parallel.ForEach is {total:N0}");
}
}
// The example displays the following output:
// The total from Parallel.ForEach is 499,999,500,000
' 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 parameter is the type of the source elements
' Second type parameter is the type of the thread-local variable (partition subtotal)
Parallel.ForEach(Of Integer, Long)(nums, Function() 0,
Function(elem, loopState, subtotal)
subtotal += elem
Return subtotal
End Function,
Sub(finalResult)
Interlocked.Add(total, finalResult)
End Sub)
Console.WriteLine("The result of Parallel.ForEach is {0:N0}", total)
End Sub
End Module
' The example displays the following output:
' The result of Parallel.ForEach is 499,999,500,000