Share via


Ekspresi Lambda di PLINQ dan TPL

Pustaka Paralel Tugas (TPL) berisi banyak metode yang mengambil salah satu System.Func<TResult> atau System.Action keluarga delegasi sebagai parameter input. Anda menggunakan delegasi ini untuk meneruskan logika program kustom Anda ke perulangan paralel, tugas, atau kueri. Contoh kode untuk TPL serta PLINQ menggunakan ekspresi lambda untuk membuat instans delegasi tersebut sebagai blok kode sebaris. Topik ini menyediakan pengantar singkat tentang Func and Action dan menunjukkan kepada Anda cara menggunakan ekspresi lambda di Pustaka Paralel Tugas dan PLINQ.

Catatan

Untuk informasi selengkapnya tentang delegasi secara umum, lihat Delegasi dan Delegasi. Untuk informasi selengkapnya tentang ekspresi lambda di C# dan Visual Basic, lihat Ekspresi Lambda dan Ekspresi Lambda.

Delegasi Func

Delegasi Func merangkum metode yang mengembalikan nilai. Dalam tanda tangan Func, parameter jenis terakhir, atau paling kanan, selalu menentukan jenis pengembalian. Salah satu penyebab umum kesalahan kompilator adalah mencoba meneruskan dua parameter input ke System.Func<T,TResult>; pada kenyataannya jenis ini hanya mengambil satu parameter input. .NET mendefinisikan 17 versi Func: System.Func<TResult>, System.Func<T,TResult>, System.Func<T1,T2,TResult>, dan sebagainya hingga System.Func<T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13,T14,T15,T16,TResult>.

Delegasi Tindakan

Delegasi System.Action merangkum metode (Sub dalam Visual Basic) yang tidak mengembalikan nilai. Dalam tanda tangan jenis Action, parameter jenis hanya mewakili parameter input. Seperti Func, .NET mendefinisikan 17 versi Action, dari versi yang tidak memiliki parameter jenis melalui versi yang memiliki 16 parameter jenis.

Contoh

Contoh berikut untuk metode Parallel.ForEach<TSource,TLocal>(IEnumerable<TSource>, Func<TLocal>, Func<TSource,ParallelLoopState,TLocal,TLocal>, Action<TLocal>) menunjukkan cara mengekspresikan delegasi Func dan Action dengan menggunakan ekspresi lambda.

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

Lihat juga