如何使用 Parallel.For(..) 在主线程上填充 List<T>
How to fill a List<T> on the main-thread using Parallel.For(..)
想象一下,对于一个拥有大量属性的学生,我得到了以下 Class,让我们将其简化为:
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 2015 年 9 月 7 日
下面的回答结果如下(524条记录):
- 2:09 分钟 - 正常循环
- 0:19 分钟 - AsParallel 循环
我宁愿使用 PLinq 而不是添加到 List<T>
(这不是线程安全的):
List<Student> allStudents = Enumerable
.Range(startRow, endRow - startRow)
.AsParallel()
.Select(i => new Student(...))
.ToList();
想象一下,对于一个拥有大量属性的学生,我得到了以下 Class,让我们将其简化为:
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 2015 年 9 月 7 日
下面的回答结果如下(524条记录):
- 2:09 分钟 - 正常循环
- 0:19 分钟 - AsParallel 循环
我宁愿使用 PLinq 而不是添加到 List<T>
(这不是线程安全的):
List<Student> allStudents = Enumerable
.Range(startRow, endRow - startRow)
.AsParallel()
.Select(i => new Student(...))
.ToList();