Notes
L’accès à cette page nécessite une autorisation. Vous pouvez essayer de vous connecter ou de modifier des répertoires.
L’accès à cette page nécessite une autorisation. Vous pouvez essayer de modifier des répertoires.
La bibliothèque parallèle de tâches (TPL) contient de nombreuses méthodes qui prennent soit l’un des délégués System.Func<TResult>, soit l’une des délégués de la famille System.Action comme paramètres d’entrée. Vous utilisez ces délégués pour transmettre votre logique de programme personnalisée à la boucle parallèle, à la tâche ou à la requête. Les exemples de code pour TPL et PLINQ utilisent des expressions lambda pour créer des instances de ces délégués en tant que blocs de code inline. Cette rubrique fournit une brève introduction à Func et Action et vous montre comment utiliser des expressions lambda dans la bibliothèque parallèle de tâches et PLINQ.
Remarque
Pour plus d’informations sur les délégués en général, consultez Délégués et Délégués. Pour plus d’informations sur les expressions lambda en C# et Visual Basic, consultez Expressions lambda et Expressions lambda.
Func (délégué)
Un Func
délégué encapsule une méthode qui retourne une valeur. Dans une Func
signature, le dernier paramètre de type ou le plus à droite spécifie toujours le type de retour. Une cause courante des erreurs du compilateur consiste à tenter de transmettre deux paramètres d’entrée à un System.Func<T,TResult>; en fait, ce type ne prend qu’un seul paramètre d’entrée. .NET définit 17 versions de Func
: System.Func<TResult>, System.Func<T,TResult>, System.Func<T1,T2,TResult>, et ainsi de suite jusqu’à .System.Func<T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13,T14,T15,T16,TResult>
Délégué d’action
Un System.Action délégué encapsule une méthode (Sub en Visual Basic) qui ne retourne pas de valeur. Dans une Action
signature de type, les paramètres de type représentent uniquement les paramètres d’entrée. Comme Func
, .NET définit 17 versions de , à partir d’une version qui n’a aucun paramètre de Action
type jusqu’à une version qui a 16 paramètres de type.
Exemple :
L’exemple suivant pour la Parallel.ForEach<TSource,TLocal>(IEnumerable<TSource>, Func<TLocal>, Func<TSource,ParallelLoopState,TLocal,TLocal>, Action<TLocal>) méthode montre comment exprimer les délégués Func et Action à l’aide d’expressions 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={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