Postupy: Zápis Parallel.For smyčky, který byl podproces místní proměnné
Tento příklad ukazuje, jak použít k ukládání a načítání stavu v každé samostatné vytvořený úkol podproces místní proměnné For smyčky. Podproces místní data pomocí se lze vyhnout režii velký počet přístupů do sdíleného stavu synchronizace. Namísto psaní ke sdílenému prostředku v každé iteraci, vypočítat a uložit hodnotu, dokud nebudou dokončeny všechny úlohy iterací. Můžete pak konečný výsledek zápis ke sdílenému prostředku nebo předat jinou metodu.
Příklad
'How to: Write a Parallel.For Loop That Has Thread-Local Variables
Imports System.Threading
Imports System.Threading.Tasks
Module ForWithThreadLocal
Sub Main()
Dim nums As Integer() = Enumerable.Range(0, 1000000).ToArray()
Dim total As Long = 0
' Use type parameter to make subtotal a Long type. Function will overflow otherwise.
Parallel.For(Of Long)(0, nums.Length, Function() 0, Function(j, [loop], subtotal)
subtotal += nums(j)
Return subtotal
End Function, Function(x) Interlocked.Add(total, x))
Console.WriteLine("The total is {0}", total)
Console.WriteLine("Press any key to exit")
Console.ReadKey()
End Sub
End Module
namespace ThreadLocalFor
{
using System;
using System.Collections.Generic;
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;
// Use type parameter to make subtotal a long, not an int
Parallel.For<long>(0, nums.Length, () => 0, (j, loop, subtotal) =>
{
subtotal += nums[j];
return subtotal;
},
(x) => Interlocked.Add(ref total, x)
);
Console.WriteLine("The total is {0}", total);
Console.WriteLine("Press any key to exit");
Console.ReadKey();
}
}
}
První dva parametry každé For metodu zadat počáteční a koncové hodnoty iterace. Toto přetížení metody je třetí parametr kde inicializovat místní státu. " Místní stát" v tomto kontextu znamená proměnné, jejichž životnost sahá od těsně před první iteraci smyčky na aktuální podproces těsně po poslední iterace.
Je třetí parametr typu Func<TResult> kde TResult je typ proměnné, uloží stav podprocesu místní. V tomto příkladu použity obecné verze metody a je parametr typu dlouhé (Long v jazyce Visual Basic) zadejte parametr kompilátoru sděluje, typ dočasnou proměnnou, který bude použit k uložení stavu podprocesu místní. Výraz () => 0 ()Function() 0 v jazyce Visual Basic) v tomto příkladu znamená, že je podproces místní proměnná inicializována na nulu. Pokud je parametr typu Typ odkazu nebo typ hodnota definovaná uživatelem, by toto Func vypadat například takto:
() => new MyClass()
Function() new MyClass()
Čtvrtý parametr typu je, kde můžete definovat logiky smyčky. Technologie IntelliSense ukazuje, že má typ Func<int, ParallelLoopState, long, long> nebo Func(Of Integer, ParallelLoopState, Long, Long). Lambda výraz očekává tři vstupní parametry v odpovídající těmto typům stejné pořadí. Návratový typ je poslední parametr typu. V tomto případě je typu dlouhé, protože jsme podle typu, který je For Typ parametru. Tato proměnná nazýváme subtotal lambda výraz a jeho vrácení Vrácená hodnota slouží k inicializaci mezisoučet v každé další opakování. Tento poslední parametr také můžete představit jako hodnotu, která je každé iteraci předány a pak localFinally Delegovat po dokončení poslední iterace.
Pátý parametr je, kde můžete definovat metodu, která bude volána jednou po dokončení počet iterací v tomto podprocesu. Typ vstupního parametru opět odpovídá parametru typu For metodu a typ vrácené lambda výraz subjektu. V tomto příkladu bude přidána hodnota proměnné na obor třídy v podprocesu bezpečným způsobem. Podproces místní proměnné pomocí jsme mít vyhnout psaní této proměnné třídy v každé iteraci každé vlákno.
Další informace o použití lambda výrazů naleznete Lambda výrazy v PLINQ a TPL.
Viz také
Koncepty
Datový paralelismus (Task Parallel Library)