首页 文章

如何将此foreach代码转换为Parallel.ForEach?

提问于
浏览
157

关于 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 重写这个例子?

4 回答

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

    Foreach loop:

    迭代按顺序进行,逐个循环从单个Thread运行 . 在每个.NET框架中都定义了foreach循环 . 慢速进程的执行速度可能较慢,因为它们是串行运行的 . 进程2在1完成之前无法启动 . 流程3在2和1完成之前无法启动...快速流程的执行速度更快,因为没有线程开销

    Parallel.ForEach:

    执行以并行方式进行 . Parallel.ForEach使用多个线程 . Parallel.ForEach在.Net 4.0及以上框架中定义 . 执行慢进程可以更快,因为它们可以并行运行进程1,2和3可以并发运行(参见下面示例中的重用线程)快速进程的执行速度较慢,因为额外的线程开销

    以下示例清楚地演示了传统foreach循环与传统循环之间的区别

    Parallel.ForEach() Example

    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();
            }
        }
    }
    

    Output

    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
    

    Using Parallel.ForEach example

    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
    
  • 6
    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
    });
    

    这将导致在循环内并行解析行 . 如果你想要一个更详细的,更少的并行类的介绍,我写了一个关于TPL的系列,其中包括一个section on Parallel.ForEach .

  • 39

    对于大文件使用以下代码(你的内存较少)

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

相关问题