Parallel.For()更新项的属性

本文关键字:属性 更新 For Parallel | 更新日期: 2023-09-27 18:11:17

假设我有一个需要更新的"不同的" person列表。我想使用Parallel.For()

方法:

public void UpdatePerson(Person row){
   row.Name = //get from cache and update property
}

public Person UpdatePerson(Person row){
   row.Name = //get from cache and update property
   return row;
}

当使用parallel . for()枚举此列表并并行运行这些更新时(即:调用此方法),使用其中一个与另一个是否有任何潜在的问题?

Parallel.For()更新项的属性

让我们暂时抛开并行部分,您想要做的是对人员列表中的项进行一些操作,您是否会选择使用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是一个委托给一个获得T类型参数的void方法。

所以使用第一种方法应该是有效的:
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;
}

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

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