Ескертпе
Бұл бетке кіру үшін қатынас шегін айқындау қажет. Жүйеге кіруді немесе каталогтарды өзгертуді байқап көруге болады.
Бұл бетке кіру үшін қатынас шегін айқындау қажет. Каталогтарды өзгертуді байқап көруге болады.
Библиотека параллельных задач (TPL) содержит множество методов, которые принимают один из System.Func<TResult> или System.Action семейства делегатов в качестве входных параметров. Эти делегаты используются для передачи пользовательской логики программы параллельному циклу, задаче или запросу. Примеры кода для TPL, а также PLINQ используют лямбда-выражения для создания экземпляров этих делегатов в виде встроенных блоков кода. В этом разделе представлено краткое введение в Func и Action и показано, как использовать лямбда-выражения в библиотеке параллельных задач и PLINQ.
Примечание.
Дополнительные сведения об делегатах в целом см. в разделе Делегаты и делегаты. Дополнительные сведения о лямбда-выражениях в C# и Visual Basic см. в разделах Лямбда-выражения и Лямбда-выражения.
Делегат Func
Делегат Func инкапсулирует метод, возвращающий значение. В Func сигнатуре последний, то есть самый правый, параметр типа всегда указывает возвращаемый тип. Одной из распространенных причин ошибок компилятора является попытка передать два входных параметра в System.Func<T,TResult>; На самом деле этот тип принимает только один входной параметр. .NET определяет 17 версий 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>.
Делегат действия
Делегат System.Action инкапсулирует метод (Sub в Visual Basic), который не возвращает значение. В сигнатуре типа Action параметры типа представляют только входные параметры. Как и Func, .NET определяет 17 версий Actionиз версии, которая не имеет параметров типа до версии с 16 параметрами типа.
Пример
В следующем примере для метода 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