Como: Criar um Loop de Parallel tem variáveis de segmento locais
O exemplo a seguir mostra como gravar um ForEach método que usa variáveis de segmento local. Quando um ForEach o loop é executado, ele divide a sua coleção de origem em várias partições. Cada partição terá sua própria cópia de "thread-local" variável. (O termo "thread-local" é um pouco impreciso aqui, porque em alguns casos, duas partições pode ser executado no mesmo thread.)
O código e os parâmetros neste exemplo parecido com o correspondente For método. Para obter mais informações, consulte Como: Criar um Loop de Parallel tem variáveis de segmento locais.
Exemplo
Para usar uma variável de segmento locais em um ForEach loop, você deve usar a versão do método que assume dois type parâmetros. O primeiro parâmetro especifica o tipo de elemento de origem e o segundo parâmetro especifica o tipo de variável de segmento local.
O primeiro parâmetro de entrada é a fonte de dados e o segundo é a função que irá inicializar a variável de segmento local. O terceiro parâmetro de entrada é um Func<T1, T2, T3, TResult> que é invocado pelo loop paralelo em cada iteração. Você fornecer o código para o representante e o loop passa os parâmetros de entrada. Os parâmetros de entrada são o elemento atual, um ParallelLoopState variável que permite que você examine o estado de loop e a variável de segmento local. Retornar a variável de segmento local e o método e passa para a próxima iteração nesta partição. Essa variável é distinto em todas as partições de loop.
O último parâmetro de entrada do ForEach método é o Action<T> representante invocará o método quando tem concluído a todos os loops. O método fornece o valor final da variável local de segmento do segmento (ou partição de loop) e fornecer o código que captura o valor final e executa qualquer ação é necessária para combinar o resultado desta partição com os resultados de outras partições. Porque o tipo de delegado é um Action<T>, não há nenhum valor de retorno.
' How to: Write a Parallel.ForEach Loop That Has Thread-Local Variables
Imports System.Threading
Imports System.Threading.Tasks
Module ForEachThreadLocal
Sub Main()
Dim nums() As Integer = Enumerable.Range(0, 1000000).ToArray()
Dim total As Long = 0
' First type paramemter is the type of the source elements
' Second type parameter is the type of the local data (subtotal)
Parallel.ForEach(Of Integer, Long)(nums, Function() 0,
Function(elem, loopState, subtotal)
subtotal += nums(elem)
Return subtotal
End Function,
Sub(finalResult)
Interlocked.Add(total, finalResult)
End Sub)
Console.WriteLine("The result of Parallel.ForEach is {0}", total)
Console.WriteLine("Press any key to exit.")
Console.ReadKey()
End Sub
End Module
namespace ThreadLocalForEach
{
using System;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
class Test
{
static void Main()
{
int[] nums = Enumerable.Range(0, 1000000).ToArray();
long total = 0;
// First type parameter is the type of the source elements
// Second type parameter is the type of the local data (subtotal)
Parallel.ForEach<int, long>(nums, // source collection
() => 0, // method to initialize the local variable
(j, loop, subtotal) => // method invoked by the loop on each iteration
{
subtotal += nums[j]; //modify local variable
return subtotal; // value to be passed to next iteration
},
// Method to be executed when all loops have completed.
// finalResult is the final value of subtotal. supplied by the ForEach method.
(finalResult) => Interlocked.Add(ref total, finalResult)
);
Console.WriteLine("The total from Parallel.ForEach is {0}", total);
Console.WriteLine("Press any key to exit");
Console.ReadKey();
}
}
}
Consulte também
Tarefas
Como: Criar um Loop de Parallel tem variáveis de segmento locais