【问题标题】:How to fill a List<T> on the main-thread using Parallel.For(..)如何使用 Parallel.For(..) 在主线程上填充 List<T>
【发布时间】:2015-09-27 21:01:37
【问题描述】:

想象一下,我为一个有很多属性的学生准备了以下课程,让我们将其简化为:

public class Student{
    public Int64 id { get; set; }
    public String name { get; set; }
    public Int64 Age { get; set; }
}

然后在主线程上我得到了以下列表:

List<Student> allStudents = new List<Student>();

假设我在一个 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);
}

现在因为在 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);
});

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

@编辑 15:52 09-07-2015

下面的回答结果如下(524条记录):

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

【问题讨论】:

    标签: c# multithreading parallel-processing locking


    【解决方案1】:

    我宁愿使用 PLinq 而不是添加到List&lt;T&gt;(这不是线程安全的):

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

    【讨论】:

    • 您能否提供更多详细信息,例如它的工作原理以及优势是什么。 (AsParallel,这是什么意思?)
    • 简而言之,AsParallel(另请参阅 AsOrderedAsSequential)允许 PLinq 在并行模式下运行以下方法(即 Select):比如说,运行Selecti == 5 不等待Select 的完整性和i == 4 msdn.microsoft.com/en-us/library/dd460688(v=vs.100).aspx
    • Enumerable.Range() 的参数表示 (start, count) 而不是 Parallel.For() (奇怪的 C# 设计决策) 中的 (start, end),因此您需要 Enumerable.Range(startRow, endRow - startRow)。除此之外,很好的答案。
    • @Dennis_E:谢谢!你说得对:一定是endRow - startRow
    • 哎呀,我没有看到最后一行。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-10-05
    • 1970-01-01
    • 1970-01-01
    • 2017-10-06
    相关资源
    最近更新 更多