假设我有一个" distinct"我需要更新的人员名单。我想使用Parallel.For()
有问题的方法:
public void UpdatePerson(Person row){
row.Name = //get from cache and update property
}
VS
public Person UpdatePerson(Person row){
row.Name = //get from cache and update property
return row;
}
当使用Parallel.For()枚举此列表并并行运行这些更新时(即调用此方法),使用一个与另一个相比是否存在任何潜在问题?
答案 0 :(得分:1)
让我们暂时离开并行部分,您想要做的是对人员列表中的项目进行一些操作,您是否会选择用于此目的循环:
for(int i = 0; i < persons.Length, i++)
{
persons[i].Name = "SomeName;
}
或foreach循环:
foreach(Person person in persons)
{
person.Name = "SomeName";
}
在这种情况下,我更喜欢使用foreach循环,因为我觉得它更合适也更清晰,在我的意见中这是一个明显的选择。
现在让我们回到并行部分,Parallel.For()应该用于并行执行for循环,而Parallel.Foreach()应该用于并行执行foreach循环。
因此,如果我们同意在这种情况下foreach循环更合适,那么我们也应该优先选择Parallel.Foreach()而不是Parallel.For()。
现在针对你的问题,Parallel.Foreach()将把一个Action的T作为参数,所以如果你想将一个方法名称传递给操作,它必须是void方法,因为Action of T是一个void方法的委托,获取一个类型为T的参数
所以使用你的第一种方法应该有效:
public void UpdatePersonName(Person person)
{
person.Name = "SomeName";
}
并行部分(使用this重载):
Parallel.Foreach(persons, UpdatePersonName);
另一种选择是使用lambda表达式而不是创建seprate方法:
Parallel.Foreach(persons, person => person.Name = "SomeName" );
由于这个原因,你不能使用第二种方法:
public Person UpdatePersonName(Person person)
{
person.Name = "SomeName";
return person;
}
在Parallel.Foreach()中,因为它的返回类型不是空的。
您应该知道的另一个重要事项,如果您使用Parallel.Foreach(),则需要确保线程安全,并且大多数时候您需要使用某种锁定来实现这一点。
你应该仔细考虑这一点,因为有时它不值得开销,在某些情况下foreach loops can run faster than their parallel equivalents。
答案 1 :(得分:-2)
返回对象是什么并不重要。 Parallel.For()将根据您执行方法的方式运行相同的内容。如果你等待返回的人使用它,那么它就不会使你的应用程序变慢,因为在更新完成之前它不会返回Person对象。
如果返回无效,那么应用程序的某些其他部分不会等待返回值,理论上应该运行得很好,无论更新何时发生。