Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/261.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 如何将此foreach代码转换为Parallel.foreach?_C#_Multithreading_.net 4.0_Parallel.foreach - Fatal编程技术网

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

C# 如何将此foreach代码转换为Parallel.foreach?,c#,multithreading,.net-4.0,parallel.foreach,C#,Multithreading,.net 4.0,Parallel.foreach,我对并行有点困惑。ForEach 什么是并行的。ForEach它到底做什么? 请不要参考任何MSDN链接 下面是一个简单的例子: string[] lines = File.ReadAllLines(txtProxyListPath.Text); List<string> list_lines = new List<string>(lines); foreach (string line in list_lines) { //My Stuff } string

我对并行有点困惑。ForEach
什么是并行的。ForEach它到底做什么?
请不要参考任何MSDN链接

下面是一个简单的例子:

string[] lines = File.ReadAllLines(txtProxyListPath.Text);
List<string> list_lines = new List<string>(lines);

foreach (string line in list_lines)
{
    //My Stuff
}
string[]lines=File.ReadAllLines(txtProxyListPath.Text);
列表\行=新列表(行);
foreach(列表行中的字符串行)
{
//我的东西
}
如何使用
Parallel.ForEach
重写此示例?

string[]line=File.ReadAllLines(txtProxyListPath.Text);
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
});
//不需要这个名单 //列表\行=新列表(行); Parallel.ForEach(行,行=> { //我的东西 });
这将导致在循环内并行解析这些行。如果您想对并行类进行更详细、更少“面向引用”的介绍,我在TPL上写了一个系列,其中包括一个。

string[]lines=File.ReadAllLines(txtProxyListPath.Text);
列表\行=新列表(行);
Parallel.ForEach(列出行,行=>
{
//你的东西
});

Foreach循环:

  • 迭代按顺序进行,一个接一个
  • foreach循环从单个线程运行
  • 在.NET的每个框架中都定义了foreach循环
  • 缓慢进程的执行可能会较慢,因为它们是连续运行的
    • 在完成1之前,进程2无法启动。流程3在完成2和1之前无法启动
  • 快速进程的执行速度更快,因为没有线程开销
并行。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);
var options = new ParallelOptions { MaxDegreeOfParallelism = Environment.ProcessorCount * 10 };
Parallel.ForEach(lines , options, (item) =>
{
 //My Stuff
});

我想补充一下并行选项。如果您没有提到,默认情况下,所有RAM都将用于此目的,这可能会给您的生产带来问题。所以最好在代码中添加最大程度的并行性

Parallel.ForEach(列出行,新的并行选项{maxdegreeofpparallelism=2},行=>
{
});

这可能在这里得到了回答@UjjwalManandhar,这实际上是非常不同的,因为它询问了
并行
类和使用PLINQ之间的区别。其他人回答了如何重写。那么它有什么作用呢?它对集合中的每个项目执行“操作”,就像普通的
foreach
。不同之处在于并行版本可以同时执行许多“操作”。在大多数情况下(取决于运行代码的计算机、它有多忙以及其他情况),它会更快,这是最重要的优势。请注意,当您并行执行此操作时,您无法知道项目的处理顺序。对于通常的(串行)
foreach
,您可以保证
行[0]
首先出现,然后是
行[1]
,依此类推。@JeppeStigNielsen它不会总是更快,因为使事情并行会有很大的开销。这取决于您正在迭代的集合的大小以及其中的操作。正确的做法是实际测量使用Parallel.ForEach()和使用ForEach()之间的差异。通常的foreach()速度要快很多倍。@DaveBlack-Sure。在每种情况下,人们都必须衡量它是快还是慢。我只是想概括地描述一下并行化。我只是想指出它(更多关于OP),这样就不会有一种错误的想法,认为它只适用于
列表
;)谢谢你的关注和回答。我在代码中使用列表,因为使用哈希列表删除重复项。使用常规数组,我们无法轻松删除重复项:)。我很困惑这个答案是否被标记为正确答案,因为没有解释原始帖子的问题“什么是Parallel.ForEach,它到底做了什么?”…@fosb问题是编辑了问题标题以完全改变其含义。。。所以这个答案不再有任何意义。尽管如此,这仍然是一个糟糕的答案。我不太同意你的说法,即Parallel.ForEach(总是)更快。这实际上取决于循环内操作的重量。这可能值得,也可能不值得引入并行的开销。每个线程的并行意味着设置单独的线程来执行循环体中的代码。尽管.NET确实有有效的机制来实现这一点,但这是相当大的开销。因此,如果您只需要一个简单的运算(例如,求和或乘法),并行foreach不应该更快。@Jignesh这甚至不是一个好的度量示例,所以我根本不会提到这个。从每个循环体中删除“Thread.Sleep(10);”,然后重试。@Martao是对的,问题在于对象锁定开销,并行方法可能比顺序方法长。@stenly我认为睡眠正是这是一个好例子的原因。你不会使用单次迭代速度快的PFE(正如Martao所解释的),所以这个答案会使迭代速度变慢,并且PFE的(正确的)优势会被强调。我同意,尽管这需要在答案中加以解释,但粗体的“总是更快”是非常误导的。
Parallel.ForEach(File.ReadLines(txtProxyListPath.Text), line => {
    //Your stuff
});
string[] lines = File.ReadAllLines(txtProxyListPath.Text);
var options = new ParallelOptions { MaxDegreeOfParallelism = Environment.ProcessorCount * 10 };
Parallel.ForEach(lines , options, (item) =>
{
 //My Stuff
});