Sdílet prostřednictvím


Lambda výrazy v PLINQ a TPL

Úkol paralelní knihovnu (TPL) obsahuje jednu z mnoha metod System.Func<TResult> nebo System.Action řady Delegáti jako vstupní parametry. Pomocí těchto delegátů předat vlastní program logiky paralelní smyčky, úkol nebo dotaz. Příklady kódu pro TPL, jakož i PLINQ slouží k vytvoření instancí těchto delegátů jako bloky kódu vloženého lambda výrazů. Toto téma obsahuje stručný úvod do Func a akce a ukazuje, jak použít lambda výrazy v úloh Knihovna paralelní a PLINQ.

**Poznámka:**Další informace o delegáty, viz Delegates (C# Programming Guide) a Delegates (Visual Basic). Další informace o lambda výrazy v jazyce C# a Visual Basic, viz Lambda Expressions (C# Programming Guide) a Lambda Expressions.

Delegát FUNC

A Func delegát Zapouzdřuje metody, který vrací hodnotu. Podpis Func parametr typu poslední nebo nejpravější vždy určuje typ vrácené. Jednou z běžných příčin chyby kompilátoru je pokus o předání dva vstupní parametry System.Func<T, TResult>; Tento typ má ve skutečnosti pouze jeden vstupní parametr. Knihovna tříd Framework definuje 17 verzí 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>.

Delegát akce

A System.Action delegát Zapouzdřuje metody (Sub v Visual Basic), vrátí hodnotu nebo vrátí void. Parametry typu podpisu typ akce představují pouze vstupní parametry. Knihovna tříd Framework definuje jako Func, 17 verzí akce, verzi, která neobsahuje žádné parametry typu přes verzi, která obsahuje 16 parametry typu.

Příklad

Následující příklad Parallel.ForEach<TSource, TLocal>(IEnumerable<TSource>, Func<TLocal>, Func<TSource, ParallelLoopState, TLocal, TLocal>, Action<TLocal>) Metoda ukazuje, jak express Delegáti Func a akce pomocí lambda výrazů.

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

}

Viz také

Koncepty

Paralelní programování v rozhraní .NET Framework