Aracılığıyla paylaş


PLINQ ve TPL'de Lambda İfadeleri

Görev Paralel Kitaplığı (TPL), System.Func<TResult> veya System.Action temsilci ailelerinden birini giriş parametresi olarak alan birçok yöntem içerir. Özel program mantığınızı paralel döngüye, göreve veya sorguya geçirmek için bu temsilcileri kullanırsınız. TPL ve PLINQ için kod örnekleri, bu temsilcilerin örneklerini satır içi kod blokları olarak oluşturmak için lambda ifadelerini kullanır. Bu konu, Func ve Eylem'e kısa bir giriş sağlar ve Görev Paralel Kitaplığı ve PLINQ'da lambda ifadelerinin nasıl kullanılacağını gösterir.

Uyarı

Genel olarak temsilciler hakkında daha fazla bilgi için bkz. Temsilciler ve Temsilciler. C# ve Visual Basic'teki lambda ifadeleri hakkında daha fazla bilgi için bkz. Lambda İfadeleri ve Lambda İfadeleri.

Func Temsilcisi

Func temsilcisi, değer döndüren bir yöntemi kapsüller. Func imzada, en son veya en sağdaki tür parametresi her zaman dönüş türünü belirtir. Derleyici hatalarının yaygın nedenlerinden biri, System.Func<T,TResult>'ye iki giriş parametresi geçirmek için bir girişimde bulunmaktır; aslında bu tür yalnızca bir giriş parametresi alır. .NET, Func17 sürümünü tanımlar: System.Func<TResult>, System.Func<T,TResult>, System.Func<T1,T2,TResult>vb. System.Func<T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13,T14,T15,T16,TResult>.

Eylem Temsilcisi

System.Action temsilcisi, değer döndürmeyen bir yöntemi (Visual Basic'te Sub) kapsüller. Action tür imzasında tür parametreleri yalnızca giriş parametrelerini temsil eder. .NET, Funcgibi, tür parametresi olmayan bir sürümden başlayarak 16 tür parametresine kadar her birine sahip olan toplam 17 Actionsürümünü tanımlar.

Örnek

Parallel.ForEach<TSource,TLocal>(IEnumerable<TSource>, Func<TLocal>, Func<TSource,ParallelLoopState,TLocal,TLocal>, Action<TLocal>) yöntemi için aşağıdaki örnekte, lambda ifadelerini kullanarak hem Func hem de Eylem temsilcilerinin nasıl ifade edildiği gösterilmektedir.

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

Ayrıca bkz.