Útmutató: Parallel.ForEach hurok írása partíció-helyi változókkal
Az alábbi példa bemutatja, hogyan írhat partíció-helyi ForEach változókat használó metódust. ForEach Egy ciklus végrehajtásakor a forrásgyűjteményt 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ók hasonlóak a szál helyi változóihoz, 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ó : How to: Write a Parallel.For Loop with Thread-Local Variables.
Ha partíció-helyi változót szeretne használni egy ForEach ciklusban, meg kell hívnia a metódus túlterheléseinek egyikét, amely két típusparamétert vesz igénybe. Az első típusparaméter, TSource
a forráselem típusát, a második típusparaméter TLocal
pedig a partíció-helyi változó típusát adja meg.
Példa
Az alábbi példa egy millió elemből álló tömb összegének kiszámítására hívja meg a Parallel.ForEach<TSource,TLocal>(IEnumerable<TSource>, Func<TLocal>, Func<TSource,ParallelLoopState,TLocal,TLocal>, Action<TLocal>) túlterhelést. Ennek a túlterhelésnek négy paramétere van:
source
, amely az adatforrás. Implementálnia IEnumerable<T>kell . A példánkban szereplő adatforrás a metódus által visszaadott Enumerable.Range egymillió tagobjektumIEnumerable<Int32>
.localInit
vagy a partíció-helyi változót inicializáló függvény. Ezt a függvényt a rendszer minden olyan partícióhoz meghívja, amelyben a Parallel.ForEach művelet fut. A példánk a partíció-helyi változót nullára inicializálja.body
, amelyet Func<T1,T2,T3,TResult> a párhuzamos hurok hív meg a ciklus minden iterációján. Az aláírása .Func\<TSource, ParallelLoopState, TLocal, TLocal>
Meg kell adnia a delegált kódját, és a hurok a bemeneti paraméterekben halad át, 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>
meghatalmazott, amelyet a Parallel.ForEach rendszer meghív, amikor az egyes partíciókban végrehajtott ciklusműveletek befejeződtek. A Parallel.ForEach metódus átadja aAction<TLocal>
delegáltnak a partíció-helyi változó végső értékét ehhez a hurokpartícióhoz, és megadja azt a kódot, amely végrehajtja a szükséges műveletet az eredmény és a többi partíció eredményeinek egyesítéséhez. Ezt a meghatalmazottat egyszerre több tevékenység is meghívhatja. Emiatt a példa a Interlocked.Add(Int32, Int32) metódus használatával szinkronizálja atotal
változóhoz való hozzáférést. 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 {0:N0}", total);
}
}
// 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
Lásd még
Visszajelzés
https://aka.ms/ContentUserFeedback.
Hamarosan elérhető: 2024-ben fokozatosan kivezetjük a GitHub-problémákat a tartalom visszajelzési mechanizmusaként, és lecseréljük egy új visszajelzési rendszerre. További információ:Visszajelzés küldése és megtekintése a következőhöz: