0

假设我有一个需要更新的“不同”人员列表。我想使用 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() 枚举此列表并并行运行这些更新(即调用此方法)时,使用一个与另一个是否有任何潜在问题?

4

1 回答 1

2

让我们暂时离开并行部分,您要做的是对人员列表中的项目进行一些操作,您是否选择为此目的使用 for 循环:

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() 将采用 T 的 Action 作为参数,因此,如果您想将方法名称传递给操作,则它必须是 void 方法,因为T 的 Action是获取一个 void 方法的委托T 型参数。

因此,使用您的第一种方法应该有效:

public void UpdatePersonName(Person person)
{
    person.Name = "SomeName";
}

和并行部分(使用这个重载):

Parallel.Foreach(persons, UpdatePersonName);

另一个替代创建单独方法的选择是使用 lambda 表达式:

Parallel.Foreach(persons, person => person.Name = "SomeName" );

由于这个原因,您不能使用第二种方法:

public Person UpdatePersonName(Person person)
{
   person.Name = "SomeName";
   return person;
}

在 Parallel.Foreach() 内部,因为它的返回类型不是 void。

您应该知道的另一件重要的事情是,如果您使用的是 Parallel.Foreach(),您将需要确保线程安全,并且大多数时候您需要使用某种锁定来实现这一点。
您应该仔细考虑这一点,因为有时它不值得开销,在某些情况下,foreach 循环可以比它们的并行等效循环运行得更快

于 2016-10-03T23:04:26.073 回答