Como: Criar um Loop de Parallel simples
Este exemplo mostra como usar um Parallel.ForEach o loop para ativar o paralelismo de dados sobre qualquer System.Collections.IEnumerable ou System.Collections.Generic.IEnumerable<T> dados de origem.
Observação
Esta documentação usa expressões lambda para definir os delegados no PLINQ.Se você não estiver familiarizado com as expressões lambda em C# ou Visual Basic, consulte Expressões lambda no PLINQ e TPL.
Exemplo
' How to: Write a Simple Parallel.ForEach Loop
' IMPORTANT!!!: Add reference to System.Drawing.dll
Imports System.Threading
Imports System.Threading.Tasks
Imports System.Drawing
Module ForEachDemo
Sub Main()
' A simple source for demonstration purposes. Modify this path as necessary.
Dim files As String() = System.IO.Directory.GetFiles("C:\Users\Public\Pictures\Sample Pictures", "*.jpg")
Dim newDir As String = "C:\Users\Public\Pictures\Sample Pictures\Modified"
System.IO.Directory.CreateDirectory(newDir)
' Method signature: Parallel.ForEach(IEnumerable<TSource> source, Action<TSource> body)
' Be sure to add a reference to System.Drawing.dll.
Parallel.ForEach(files, Sub(currentFile)
' The more computational work you do here, the greater
' the speedup compared to a sequential foreach loop.
Dim filename As String = System.IO.Path.GetFileName(currentFile)
Dim bitmap As New System.Drawing.Bitmap(currentFile)
bitmap.RotateFlip(System.Drawing.RotateFlipType.Rotate180FlipNone)
bitmap.Save(System.IO.Path.Combine(newDir, filename))
' Peek behind the scenes to see how work is parallelized.
' But be aware: Thread contention for the Console slows down parallel loops!!!
Console.WriteLine("Processing {0} on thread {1}", filename, Thread.CurrentThread.ManagedThreadId)
'close lambda expression and method invocation
End Sub)
' Keep the console window open in debug mode.
Console.WriteLine("Processing complete. Press any key to exit.")
Console.ReadKey()
End Sub
End Module
namespace ForEachDemo
{
using System;
using System.Drawing; // requires system.Drawing.dll
using System.IO;
using System.Threading;
using System.Threading.Tasks;
class SimpleForEach
{
static void Main()
{
// A simple source for demonstration purposes. Modify this path as necessary.
string[] files = System.IO.Directory.GetFiles(@"C:\Users\Public\Pictures\Sample Pictures", "*.jpg");
string newDir = @"C:\Users\Public\Pictures\Sample Pictures\Modified";
System.IO.Directory.CreateDirectory(newDir);
// Method signature: Parallel.ForEach(IEnumerable<TSource> source, Action<TSource> body)
Parallel.ForEach(files, currentFile =>
{
// The more computational work you do here, the greater
// the speedup compared to a sequential foreach loop.
string filename = System.IO.Path.GetFileName(currentFile);
System.Drawing.Bitmap bitmap = new System.Drawing.Bitmap(currentFile);
bitmap.RotateFlip(System.Drawing.RotateFlipType.Rotate180FlipNone);
bitmap.Save(System.IO.Path.Combine(newDir, filename));
// Peek behind the scenes to see how work is parallelized.
// But be aware: Thread contention for the Console slows down parallel loops!!!
Console.WriteLine("Processing {0} on thread {1}", filename,
Thread.CurrentThread.ManagedThreadId);
} //close lambda expression
); //close method invocation
// Keep the console window open in debug mode.
Console.WriteLine("Processing complete. Press any key to exit.");
Console.ReadKey();
}
}
}
A ForEach loop funciona como um For loop. A coleção de origem está particionada e o trabalho é agendado em vários segmentos, com base no ambiente do sistema. Quanto mais processadores no sistema, é executado mais rápido do método paralelo. Para algumas coleções de origem, um loop seqüencial pode ser mais rápido, dependendo do tamanho de fonte e o tipo de trabalho que está sendo executado. Para obter mais informações sobre o desempenho, consultePossíveis armadilhas em dados e o paralelismo de tarefas
Para obter mais informações sobre loops paralelos, consulte Como: Criar um Loop de Parallel. for simples.
Para usar ForEach com uma coleção não genéricas, você pode usar o Cast<TResult> o método de extensão para converter a coleção para uma coleção genérica, conforme mostrado no exemplo a seguir:
Parallel.ForEach(nonGenericCollection.Cast(Of Object), _
Sub(currentElement)
' ... work with currentElement
End Sub)
Parallel.ForEach(nonGenericCollection.Cast<object>(),
currentElement =>
{
});
Você também pode usar o PLINQ (Parallel LINQ) para paralelizar o processamento de IEnumerable<T> fontes de dados. PLINQ permite que você use a sintaxe de consulta declarativa para expressar o comportamento de loop. Para obter mais informações, consulte Parallel LINQ PLINQ).
Compilando o código
Copie e cole este código em um Visual Studio projeto de aplicativo de Console de 2010.
Adicionar uma referência para System.Drawing.dll
Pressione F5
Consulte também
Conceitos
Paralelismo de dados (biblioteca paralela de tarefas)