如何使用Parallel.For(..)填充主线程上的List <T>

Sli*_*009 4 c# parallel-processing multithreading locking

想象一下,我为一个有很多属性的学生提供了以下课程,让我们简化它:

public class Student{
    public Int64 id { get; set; }
    public String name { get; set; }
    public Int64 Age { get; set; }
}
Run Code Online (Sandbox Code Playgroud)

然后在主线程上我有以下列表:

List<Student> allStudents = new List<Student>();
Run Code Online (Sandbox Code Playgroud)

假设我在Excel文件中有500名学生,我想收集它们并将它们插入列表中.我可以做如下的事情:

for(int i = startRow; i < endRow; i++){
    Student s = new Student();

    //Perform a lot of actions to gather all the information standing on the row//

    allStudents.Add(s);
}
Run Code Online (Sandbox Code Playgroud)

现在因为在Excel中收集信息非常慢,因为必须执行许多操作.所以我想使用Parallel.For,我可以想象做以下事情:

Parallel.For(startRow, endRow, i => {
    Student s = new Student();

    //Perform a lot of actions to gather all the information standing on the row//

    //Here comes my problem. I want to add it to the collection on the main-thread.
    allStudents.Add(s);
});
Run Code Online (Sandbox Code Playgroud)

在上述问题中实现Parallel.For的正确方法是什么?我应该在添加之前锁定列表吗?具体如何?

@Edit 15:52 09-07-2015

以下答案的结果如下(524条记录):

  • 2:09分钟 - 正常循环
  • 0:19分钟 - AsParallel循环

Dmi*_*nko 9

我宁愿使用PLinq而不是添加List<T>(这不是线程安全的):

List<Student> allStudents = Enumerable
  .Range(startRow, endRow - startRow)
  .AsParallel()
  .Select(i => new Student(...))
  .ToList();
Run Code Online (Sandbox Code Playgroud)

  • 用几句话来说,"AsParallel"(看看`AsOrdered`和`AsSequential`)允许*PLinq*在并行模式下运行下面的方法(即`Select`):比如说,用`i == 5`运行`Select`用'i == 4`等待`Select`的完整性https://msdn.microsoft.com/en-us/library/dd460688(v=vs.100).aspx (2认同)
  • `Enumerable.Range()`的参数表示(start,count)而不是(start,end),如`Parallel.For()`(奇怪的C#设计决策),所以你需要`Enumerable.Range(startRow,endRow) - startRow)` 除此之外,优秀的答案. (2认同)