Delen via


Lambda-expressies in PLINQ en TPL

De Task Parallel Library (TPL) bevat veel methoden die een van de System.Func<TResult> of System.Action familie gedelegeerden als invoerparameters gebruiken. U gebruikt deze gemachtigden om uw aangepaste programmalogica door te geven aan de parallelle lus, taak of query. In de codevoorbeelden voor TPL en PLINQ worden lambda-expressies gebruikt om exemplaren van deze gemachtigden te maken als inlinecodeblokken. Dit onderwerp bevat een korte inleiding tot Func en Action en laat zien hoe u lambda-expressies gebruikt in de taakparallelbibliotheek en PLINQ.

Notitie

Zie Gemachtigden en gemachtigden voor meer informatie over gemachtigden in het algemeen. Zie Lambda-expressies en Lambda-expressies voor meer informatie over lambda-expressies in C# en Visual Basic.

Func Delegate

Een Func gedelegeerde bevat een methode die een waarde retourneert. In een Func handtekening, de laatste of meest rechtse, typeparameter geeft altijd het retourtype op. Een veelvoorkomende oorzaak van compilerfouten is het doorgeven van twee invoerparameters aan een System.Func<T,TResult>; in feite heeft dit type slechts één invoerparameter nodig. .NET definieert 17 versies vanFunc: System.Func<TResult>, System.Func<T,TResult>, enzovoortSystem.Func<T1,T2,TResult>.System.Func<T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13,T14,T15,T16,TResult>

Actie gedelegeerde

Een System.Action gedelegeerde bevat een methode (Sub in Visual Basic) die geen waarde retourneert. In een Action typehandtekening vertegenwoordigen de typeparameters alleen invoerparameters. Net definieert Func.NET 17 versies van Action, van een versie die geen typeparameters heeft tot een versie met 16 typeparameters.

Opmerking

In het volgende voorbeeld voor de Parallel.ForEach<TSource,TLocal>(IEnumerable<TSource>, Func<TLocal>, Func<TSource,ParallelLoopState,TLocal,TLocal>, Action<TLocal>) methode ziet u hoe u zowel Func- als Action-gemachtigden kunt uitdrukken met behulp van lambda-expressies.

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

Zie ook