Lambdaausdrücke in PLINQ und TPLLambda Expressions in PLINQ and TPL

Die Task Parallel Library (TPL) enthält viele Methoden, die eine der System.Func<TResult>- oder System.Action-Delegatenfamilien als Eingabeparameter annehmen.The Task Parallel Library (TPL) contains many methods that take one of the System.Func<TResult> or System.Action family of delegates as input parameters. Sie verwenden diese Delegaten zur Übergabe der benutzerdefinierten Programmlogik an die parallele Schleife, Aufgabe oder Abfrage.You use these delegates to pass in your custom program logic to the parallel loop, task or query. In den Codebeispielen für TPL und PLINQ werden Lambdaausdrücke verwendet, um Instanzen dieser Delegaten als Inlinecodeblöcke zu erstellen.The code examples for TPL as well as PLINQ use lambda expressions to create instances of those delegates as inline code blocks. Dieses Thema bietet eine kurze Einführung in Func und Action und zeigt, wie Sie Lambdaausdrücke in der Task Parallel Library und in PLINQ verwenden.This topic provides a brief introduction to Func and Action and shows you how to use lambda expressions in the Task Parallel Library and PLINQ.

Hinweis

Weitere allgemeine Informationen zu Delegaten finden Sie unter Delegaten (C#-Programmierhandbuch) und Delegaten (Visual Basic).For more information about delegates in general, see Delegates and Delegates. Weitere Informationen zu Lambdaausdrücken in C# und Visual Basic finden Sie unter Lambdaausdrücke (C#-Programmierhandbuch) und Lambdaausdrücke (Visual Basic).For more information about lambda expressions in C# and Visual Basic, see Lambda Expressions and Lambda Expressions.

Func-DelegatFunc Delegate

Ein Func-Delegat kapselt eine Methode, die einen Wert zurückgibt.A Func delegate encapsulates a method that returns a value. In einer Func-Signatur gibt der letzte bzw. der am weitesten rechts stehende Typparameter immer den Rückgabetyp an.In a Func signature, the last or rightmost type parameter always specifies the return type. 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.One common cause of compiler errors is to attempt to pass in two input parameters to a System.Func<T,TResult>; in fact this type takes only one input parameter. Die 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>.The Framework Class Library defines 17 versions of Func: System.Func<TResult>, System.Func<T,TResult>, System.Func<T1,T2,TResult>, and so on up through System.Func<T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13,T14,T15,T16,TResult>.

Action-DelegatAction Delegate

Ein System.Action-Delegat kapselt eine Methode (Untermethode in Visual Basic), die keinen Wert oder void zurückgibt.A System.Action delegate encapsulates a method (Sub in Visual Basic) that does not return a value, or returns void. In einer Signatur vom Typ „Action“ stellen die Typparameter nur Eingabeparameter dar.In an Action type signature, the type parameters represent only input parameters. Die .NET Framework-Klassenbibliothek definiert wie bei Func 17 Versionen von Action, von einer Version ohne Typparameter bis zu einer Version mit 16 Typparametern.Like Func, the Framework Class Library defines 17 versions of Action, from a version that has no type parameters up through a version that has 16 type parameters.

BeispielExample

Das folgende Beispiel für die Parallel.ForEach<TSource,TLocal>(IEnumerable<TSource>, Func<TLocal>, Func<TSource,ParallelLoopState,TLocal,TLocal>, Action<TLocal>)-Methode veranschaulicht, wie Func- und Action-Delegaten mithilfe von Lambdaausdrücken ausgedrückt werden.The following example for the Parallel.ForEach<TSource,TLocal>(IEnumerable<TSource>, Func<TLocal>, Func<TSource,ParallelLoopState,TLocal,TLocal>, Action<TLocal>) method shows how to express both Func and Action delegates by using lambda expressions.

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={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);
        }
    }

}
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

Siehe auchSee also