Parallel.For()更新项

时间:2016-10-03 21:10:22

标签: c# .net parallel-for

假设我有一个" 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()枚举此列表并并行运行这些更新时(即调用此方法),使用一个与另一个相比是否存在任何潜在问题?

2 个答案:

答案 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循环更合适,那么我们也应该优先选择Para​​llel.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对象。

如果返回无效,那么应用程序的某些其他部分不会等待返回值,理论上应该运行得很好,无论更新何时发生。