TPL(작업 병렬 라이브러리)에는 System.Func<TResult> 또는 System.Action 대리자 패밀리 중 하나를 입력 매개 변수로 사용하는 여러 메서드가 포함되어 있습니다. 이러한 대리자를 사용하여 사용자 지정 프로그램 논리를 병렬 루프, 작업 또는 쿼리에 전달합니다. TPL 및 PLINQ에 대한 코드 예제는 람다 식을 사용하여 이러한 대리자의 인스턴스를 인라인 코드 블록으로 만듭니다. 이 항목에서는 Func 및 Action을 간략하게 소개하고 작업 병렬 라이브러리 및 PLINQ에서 람다 식을 사용하는 방법을 보여 줍니다.
Func 대리자
Func
대리자는 값을 반환하는 메서드를 캡슐화합니다.
Func
서명에서 마지막 또는 맨 오른쪽에 있는 형식 매개 변수는 항상 반환 형식을 지정합니다. 컴파일러 오류의 일반적인 원인 중 하나는 두 개의 입력 매개 변수를 System.Func<T,TResult>전달하려고 시도하는 것입니다. 실제로 이 형식은 하나의 입력 매개 변수만 사용합니다. .NET은 Func
, System.Func<TResult>, System.Func<T,TResult>, System.Func<T1,T2,TResult>등으로부터 System.Func<T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13,T14,T15,T16,TResult>까지 총 17가지 버전을 정의합니다.
작업 대리자
System.Action 대리자는 값을 반환하지 않는 메서드(Visual Basic의 Sub)를 캡슐화합니다.
Action
형식 서명에서 형식 매개 변수는 입력 매개 변수만 나타냅니다.
Func
마찬가지로 .NET은 형식 매개 변수가 없는 버전부터 16개의 형식 매개 변수가 있는 버전을 통해 17개의 Action
버전을 정의합니다.
예시
Parallel.ForEach<TSource,TLocal>(IEnumerable<TSource>, Func<TLocal>, Func<TSource,ParallelLoopState,TLocal,TLocal>, Action<TLocal>) 메서드에 대한 다음 예제에서는 람다 식을 사용하여 Func 및 Action 대리자를 모두 표현하는 방법을 보여 줍니다.
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
참고하십시오
.NET