Poznámka
Přístup k této stránce vyžaduje autorizaci. Můžete se zkusit přihlásit nebo změnit adresáře.
Přístup k této stránce vyžaduje autorizaci. Můžete zkusit změnit adresáře.
Následující příklad ukazuje, jak napsat metodu ForEach , která používá proměnné partition-local. Když se smyčka ForEach spustí, rozdělí zdrojovou kolekci do několika oddílů. Každý oddíl má svou vlastní kopii proměnné specifické pro tento oddíl. Proměnná lokální pro oddíl je podobná proměnné lokální pro vlákno, s tím rozdílem, že na jednom vlákně může běžet více oddílů.
Kód a parametry v tomto příkladu se podobají odpovídající For metodě. Další informace najdete v tématu Postupy: Zápis smyčky Parallel.For s Thread-Local proměnnými.
Chcete-li ve smyčce použít místní proměnnou oddílu ForEach , musíte volat jedno z přetížení metody, které přebírá dva parametry typu. První parametr typu , TSource
, určuje typ zdrojového elementu a druhý typ parametr, TLocal
určuje typ partition-local proměnné.
Příklad
Následující příklad volá funkci přetížení Parallel.ForEach<TSource,TLocal>(IEnumerable<TSource>, Func<TLocal>, Func<TSource,ParallelLoopState,TLocal,TLocal>, Action<TLocal>) pro výpočet součtu pole obsahujícího jeden milion elementů. Toto přetížení má čtyři parametry:
source
, což je zdroj dat. Musí implementovat IEnumerable<T>. Zdroj dat v našem příkladu je objekt jednoho milionu členůIEnumerable<Int32>
vrácený metodou Enumerable.Range .localInit
nebo funkci, která inicializuje místní proměnnou oddílu. Tato funkce se volá jednou pro každý oddíl, ve kterém se Parallel.ForEach operace provede. Náš příklad inicializuje místní proměnnou oddílu na nulu.body
Func<T1,T2,T3,TResult>, kterou vyvolá paralelní smyčka při každé z jejích iterací. Jeho podpis jeFunc\<TSource, ParallelLoopState, TLocal, TLocal>
. Zadáte kód pro delegáta a smyčka předává vstupní parametry, které jsou:Aktuální prvek IEnumerable<T>.
Proměnná ParallelLoopState , kterou můžete použít v kódu delegáta k prozkoumání stavu smyčky.
Místní proměnná oddílu.
Váš delegát vrátí místní proměnnou oddílu, která se pak předá další iteraci smyčky, která se provede v daném oddílu. Každá část smyčky uchovává samostatnou instanci této proměnné.
V tomto příkladu delegát přidá hodnotu každého celého čísla do místní proměnné oddílu, která udržuje průběžný součet hodnot celočíselných prvků v tomto oddílu.
localFinally
,Action<TLocal>
delegát, který Parallel.ForEach vyvolá, když se operace smyčky v každém oddílu dokončí. Metoda Parallel.ForEach předává vašemu delegátoviAction<TLocal>
konečnou hodnotu proměnné místní pro část v této části smyčky, a vy zadáte kód, který provede potřebnou akci, aby zkombinoval výsledek z této části s výsledky z ostatních částí. Tento delegát může být vyvolán souběžně několika úlohami. Z tohoto důvodu příklad používá metodu Interlocked.Add(Int32, Int32) k synchronizaci přístupu ktotal
proměnné. Vzhledem k tomu, že typ delegáta je , Action<T>neexistuje žádná návratová hodnota.
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