Anteckning
Åtkomst till den här sidan kräver auktorisering. Du kan prova att logga in eller ändra kataloger.
Åtkomst till den här sidan kräver auktorisering. Du kan prova att ändra kataloger.
Biblioteket för parallella uppgifter (TPL) innehåller många metoder som tar en av System.Func<TResult>- eller System.Action-delegatfamiljerna som inmatningsparametrar. Du använder dessa delegeringar för att överföra din anpassade programlogik till den parallella loopen, uppgiften eller frågan. Kodexemplen för TPL och PLINQ använder lambda-uttryck för att skapa instanser av dessa delegater som inline-kodblock. Det här avsnittet innehåller en kort introduktion till Func och Action och visar hur du använder lambda-uttryck i Aktivitetsparallellt bibliotek och PLINQ.
Anmärkning
Mer information om delegater finns i Delegater och Delegater. Mer information om lambda-uttryck i C# och Visual Basic finns i Lambda-uttryck och Lambda-uttryck.
Func-ombud
Ett Func delegat kapslar in en metod som returnerar ett värde. I en Func signatur anger den sista eller den högra parametern alltid returtypen. En vanlig orsak till kompilatorfel är att försöka skicka in två indataparametrar till en System.Func<T,TResult>; I själva verket tar den här typen bara en indataparameter. .NET definierar 17 versioner av Func: System.Func<TResult>, System.Func<T,TResult>, System.Func<T1,T2,TResult>och så vidare upp via System.Func<T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13,T14,T15,T16,TResult>.
Åtgärdsdelegat
En System.Action delegering kapslar in en metod (Sub i Visual Basic) som inte returnerar ett värde. I en Action typsignatur representerar typparametrarna endast indataparametrar. Precis som Funcdefinierar .NET 17 versioner av Action, från en version som inte har några typparametrar upp via en version som har 16 typparametrar.
Exempel
Följande exempel för metoden Parallel.ForEach<TSource,TLocal>(IEnumerable<TSource>, Func<TLocal>, Func<TSource,ParallelLoopState,TLocal,TLocal>, Action<TLocal>) visar hur du uttrycker både Func- och Action-ombud med hjälp av lambda-uttryck.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
class ForEachWithThreadLocal
{
// Demonstrated features:
// Parallel.ForEach()
// Thread-local state
// Expected results:
// This example sums up the elements of an int[] in parallel.
// Each thread maintains a local sum. When a thread is initialized, that local sum is set to 0.
// On every iteration the current element is added to the local sum.
// When a thread is done, it safely adds its local sum to the global sum.
// After the loop is complete, the global sum is printed out.
// Documentation:
// http://msdn.microsoft.com/library/dd990270(VS.100).aspx
static void Main()
{
// The sum of these elements is 40.
int[] input = { 4, 1, 6, 2, 9, 5, 10, 3 };
int sum = 0;
try
{
Parallel.ForEach(
input, // source collection
() => 0, // thread local initializer
(n, loopState, localSum) => // body
{
localSum += n;
Console.WriteLine("Thread={0}, n={1}, localSum={2}", Thread.CurrentThread.ManagedThreadId, n, localSum);
return localSum;
},
(localSum) => Interlocked.Add(ref sum, localSum) // thread local aggregator
);
Console.WriteLine($"\nSum={sum}");
}
// No exception is expected in this example, but if one is still thrown from a task,
// it will be wrapped in AggregateException and propagated to the main thread.
catch (AggregateException e)
{
Console.WriteLine($"Parallel.ForEach has thrown an exception. THIS WAS NOT EXPECTED.\n{e}");
}
}
}
Imports System.Threading
Imports System.Threading.Tasks
Module ForEachDemo
' Demonstrated features:
' Parallel.ForEach()
' Thread-local state
' Expected results:
' This example sums up the elements of an int[] in parallel.
' Each thread maintains a local sum. When a thread is initialized, that local sum is set to 0.
' On every iteration the current element is added to the local sum.
' When a thread is done, it safely adds its local sum to the global sum.
' After the loop is complete, the global sum is printed out.
' Documentation:
' http://msdn.microsoft.com/library/dd990270(VS.100).aspx
Private Sub ForEachDemo()
' The sum of these elements is 40.
Dim input As Integer() = {4, 1, 6, 2, 9, 5, _
10, 3}
Dim sum As Integer = 0
Try
' source collection
Parallel.ForEach(input,
Function()
' thread local initializer
Return 0
End Function,
Function(n, loopState, localSum)
' body
localSum += n
Console.WriteLine("Thread={0}, n={1}, localSum={2}", Thread.CurrentThread.ManagedThreadId, n, localSum)
Return localSum
End Function,
Sub(localSum)
' thread local aggregator
Interlocked.Add(sum, localSum)
End Sub)
Console.WriteLine(vbLf & "Sum={0}", sum)
Catch e As AggregateException
' No exception is expected in this example, but if one is still thrown from a task,
' it will be wrapped in AggregateException and propagated to the main thread.
Console.WriteLine("Parallel.ForEach has thrown an exception. THIS WAS NOT EXPECTED." & vbLf & "{0}", e)
End Try
End Sub
End Module