Hinweis
Für den Zugriff auf diese Seite ist eine Autorisierung erforderlich. Sie können versuchen, sich anzumelden oder das Verzeichnis zu wechseln.
Für den Zugriff auf diese Seite ist eine Autorisierung erforderlich. Sie können versuchen, das Verzeichnis zu wechseln.
Die Task Parallel Library (TPL) enthält viele Methoden, die eine der System.Func<TResult>- oder System.Action-Delegatfamilien als Eingabeparameter zulassen. Sie verwenden diese Delegaten zur Übergabe der benutzerdefinierten Programmlogik an die parallele Schleife, Aufgabe oder Abfrage. In den Codebeispielen für TPL und PLINQ werden Lambda-Ausdrücke verwendet, um Instanzen dieser Delegaten als Inlinecodeblöcke zu erstellen. Dieses Thema bietet eine kurze Einführung in Func und Action und zeigt, wie Sie Lambda-Ausdrücke in der Task Parallel Library und in PLINQ verwenden.
Hinweis Weitere Informationen zu Delegaten im Allgemeinen finden Sie unter Delegaten (C#-Programmierhandbuch) und Delegaten (Visual Basic). Weitere Informationen zu Lambda-Ausdrücken in C# und Visual Basic finden Sie unter Lambda-Ausdrücke (C#-Programmierhandbuch) und Lambda-Ausdrücke (Visual Basic).
Func-Delegat
Ein Func-Delegat kapselt eine Methode, die einen Wert zurückgibt. In einer Func-Signatur gibt der letzte bzw. der am weitesten rechts stehende Typparameter immer den Rückgabetyp an. Eine häufige Ursache von Compilerfehlern ist der Versuch, zwei Eingabeparameter an eine System.Func<T, TResult> zu übergeben. Dieser Typ akzeptiert jedoch nur einen Eingabeparameter. Die .NET Framework-Klassenbibliothek definiert 17 Versionen von Func: System.Func<TResult>, System.Func<T, TResult>, System.Func<T1, T2, TResult> usw. bis System.Func<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, TResult>.
Action-Delegat
Ein System.Action-Delegat kapselt eine Methode (Untermethode in Visual Basic), die keinen Wert oder void zurückgibt. In einer Signatur vom Typ "Action" stellen die Typparameter nur Eingabeparameter dar. Die .NET Framework-Klassenbibliothek definiert wie bei Func 17 Versionen von Action, von einer Version ohne Typparameter bis zu einer Version mit 16 Typparametern.
Beispiel
Im folgenden Beispiel für die Parallel.ForEach<TSource, TLocal>(IEnumerable<TSource>, Func<TLocal>, Func<TSource, ParallelLoopState, TLocal, TLocal>, Action<TLocal>)-Methode wird gezeigt, wie der Func-Delegat und der Action-Delegat mit Lambda-Ausdrücken angegeben werden.
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:
' https://msdn.microsoft.com/en-us/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
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:
// https://msdn.microsoft.com/en-us/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={0}", 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{0}", e);
}
}
}