Оставим на минуту параллельная часть, что вы хотите сделать некоторые opertaion по пунктам в списке лиц, вы решили использовать для этой цели цикл:
for(int i = 0; i < persons.Length, i++)
{
persons[i].Name = "SomeName;
}
Или цикл по каждому элементу :
foreach(Person person in persons)
{
person.Name = "SomeName";
}
Я предпочитаю использовать цикл Еогеаспа в этом случае, потому что я считаю его гораздо более удобным и ясно, в моем opnion, что является очевидным выбором.
Теперь вернемся к параллельной части, для выполнения параллельных циклов для параллельных циклов, а Parallel.Foreach() следует использовать для параллельного выполнения циклов foreach.
Итак, если мы согласились с тем, что петля foreach была более уместна в этом случае, мы также должны предпочесть Parallel.Foreach() над Parallel.For().
Теперь для вашего вопроса Parallel.Foreach() примет действие T как аргумент, поэтому, если вы хотите передать имя метода операции, это должен быть метод void, поскольку Action of T является делегатом метода void который получает один параметр типа T.
Таким образом, используя свой первый подход должен работать:
public void UpdatePersonName(Person person)
{
person.Name = "SomeName";
}
и параллельная часть (с помощью this перегрузки):
Parallel.Foreach(persons, UpdatePersonName);
Другой вариант вместо создания 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.
Вам нужно показать код, который вызывает 'UpdatePerson', также является' // получить из кеша и свойства update 'thread safe? Может ли он использоваться одновременно из нескольких потоков без проблем? Наконец, если свойство 'Name' не является объектом с автоматическим имплантированием, вам также нужно показать нам это. –
Реализация кэша не является потокобезопасной. Однако для этой дискуссии предположим, что я написал в кеш до выполнения Parallel.for и никаких изменений не будет написано, между тем, имеет ли это значение? Чтение из кеша на основе уникального идентификатора и (зная, что все люди в списке различны) имеет значение? Поскольку одна задача получит значение для id 1. другой id 2 и т. Д. (В то же время, но разные идентификаторы) – ShaneKm