Megjegyzés
Az oldalhoz való hozzáféréshez engedély szükséges. Megpróbálhat bejelentkezni vagy módosítani a címtárat.
Az oldalhoz való hozzáféréshez engedély szükséges. Megpróbálhatja módosítani a címtárat.
A Feladat párhuzamos kódtára (TPL) számos olyan metódust tartalmaz, amelyek a System.Func<TResult> meghatalmazottak egyikét vagy System.Action családját bemeneti paraméterként veszik figyelembe. Ezeket a delegátumokat használva adhatja át saját programlogikáját a párhuzamos ciklusnak, feladatnak vagy lekérdezésnek. A TPL-hez és a PLINQ-hoz használt példakód lambdakifejezésekkel hozza létre a meghatalmazottak példányait beágyazott kódblokkokként. Ez a témakör röviden bemutatja a Func és a Action használatát, és bemutatja, hogyan használhatja a lambda kifejezéseket a feladat párhuzamos kódtárában és a PLINQ-ban.
Megjegyzés
A meghatalmazottakról általában a Meghatalmazottak és meghatalmazottak című témakörben olvashat bővebben. A C# és a Visual Basic lambda kifejezéseiről további információt a Lambda-kifejezések és a Lambda-kifejezések című témakörben talál.
Func-meghatalmazott
A Func
meghatalmazott olyan metódust ágyaz be, amely egy értéket ad vissza.
Func
Az aláírásban az utolsó vagy a jobb szélső típusparaméter mindig a visszatérési típust adja meg. A fordítóhibák egyik gyakori oka, hogy két bemeneti paramétert próbál meg átadni egy System.Func<T,TResult>adott paraméternek, valójában ez a típus csak egy bemeneti paramétert vesz igénybe. A .NET a Func
17 verzióját határozza meg: System.Func<TResult>, System.Func<T,TResult>, System.Func<T1,T2,TResult>, és így tovább egészen System.Func<T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13,T14,T15,T16,TResult>-ig.
Akciódelegált
A System.Action delegáló egy olyan metódust (Sub a Visual Basic-ben) ágyaz be, amely nem ad vissza értéket.
Action
Egy típus-aláírásban a típusparaméterek csak bemeneti paramétereket jelölnek.
Func
'hoz hasonlóan, a .NET 17 különböző verziót határoz meg a Action
számára, kezdve egy olyan verzióval, amely nem rendelkezik típusparaméterekkel, egészen egy olyan verzióig, amely 16 típusparaméterrel rendelkezik.
Példa
A metódushoz tartozó Parallel.ForEach<TSource,TLocal>(IEnumerable<TSource>, Func<TLocal>, Func<TSource,ParallelLoopState,TLocal,TLocal>, Action<TLocal>) alábbi példa bemutatja, hogyan fejezheti ki a Func és a Action delegáltjait lambdakifejezések használatával.
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