何时使用Parallel.ForEach循环而不是常规的foreach?

我对Parallel.ForEach有些困惑。
什么是Parallel.ForEach ,它究竟干什么?
请不要参考任何MSDN链接。

这是一个简单的例子:

 string[] lines = File.ReadAllLines(txtProxyListPath.Text); List<string> list_lines = new List<string>(lines); foreach (string line in list_lines) { //My Stuff } 

我如何用Parallel.ForEach重写这个例子?

 string[] lines = File.ReadAllLines(txtProxyListPath.Text); List<string> list_lines = new List<string>(lines); Parallel.ForEach(list_lines, line => { //Your stuff }); 

Foreach循环:

  • 迭代依次进行,一个接一个
  • foreach循环从单个线程运行。
  • foreach循环在.NET的每个框架中定义
  • 进程的执行可能会比较 ,因为它们是连续运行的
    • 进程2不能启动,直到1完成。 进程3不能启动,直到2&1完成…
  • 执行快速stream程可以更快 ,因为没有线程开销

Parallel.ForEach:

  • 执行以并行的方式进行。
  • Parallel.ForEach使用多个线程。
  • Parallel.ForEach在.NET 4.0及以上框架中定义。
  • 进程的执行可以更快 ,因为它们可以并行运行
    • 进程1,2和3 可以同时运行(参见下面例子中的重用线程)
  • 由于额外的线程开销,执行快速进程可能会变慢

下面的例子清楚地表明了传统的foreach循环和

Parallel.ForEach()示例

 using System; using System.Diagnostics; using System.Threading; using System.Threading.Tasks; namespace ParallelForEachExample { class Program { static void Main() { string[] colors = { "1. Red", "2. Green", "3. Blue", "4. Yellow", "5. White", "6. Black", "7. Violet", "8. Brown", "9. Orange", "10. Pink" }; Console.WriteLine("Traditional foreach loop\n"); //start the stopwatch for "for" loop var sw = Stopwatch.StartNew(); foreach (string color in colors) { Console.WriteLine("{0}, Thread Id= {1}", color, Thread.CurrentThread.ManagedThreadId); Thread.Sleep(10); } Console.WriteLine("foreach loop execution time = {0} seconds\n", sw.Elapsed.TotalSeconds); Console.WriteLine("Using Parallel.ForEach"); //start the stopwatch for "Parallel.ForEach" sw = Stopwatch.StartNew(); Parallel.ForEach(colors, color => { Console.WriteLine("{0}, Thread Id= {1}", color, Thread.CurrentThread.ManagedThreadId); Thread.Sleep(10); } ); Console.WriteLine("Parallel.ForEach() execution time = {0} seconds", sw.Elapsed.TotalSeconds); Console.Read(); } } } 

产量

 Traditional foreach loop 1. Red, Thread Id= 10 2. Green, Thread Id= 10 3. Blue, Thread Id= 10 4. Yellow, Thread Id= 10 5. White, Thread Id= 10 6. Black, Thread Id= 10 7. Violet, Thread Id= 10 8. Brown, Thread Id= 10 9. Orange, Thread Id= 10 10. Pink, Thread Id= 10 foreach loop execution time = 0.1054376 seconds 

使用Parallel.ForEach示例

 1. Red, Thread Id= 10 3. Blue, Thread Id= 11 4. Yellow, Thread Id= 11 2. Green, Thread Id= 10 5. White, Thread Id= 12 7. Violet, Thread Id= 14 9. Orange, Thread Id= 13 6. Black, Thread Id= 11 8. Brown, Thread Id= 10 10. Pink, Thread Id= 12 Parallel.ForEach() execution time = 0.055976 seconds 
 string[] lines = File.ReadAllLines(txtProxyListPath.Text); // No need for the list // List<string> list_lines = new List<string>(lines); Parallel.ForEach(lines, line => { //My Stuff }); 

这将导致线路在循环内并行parsing。 如果你想要一个更详细的,更less的“引用导向”的Parallel类的介绍,我写了一个关于TPL的系列文章,其中包括一个关于Parallel.ForEach的章节 。

对于大文件使用下面的代码(你less了内存饿)

 Parallel.ForEach(File.ReadLines(txtProxyListPath.Text), line => { //Your stuff });