2016-10-03 6 views
-1

Предположим, у меня есть «отличный» список лиц, которые мне нужно обновить. Я хотел бы использовать Parallel.For()Параллельные.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(), чтобы перечислить этот список и запустить эти обновления параллельно (т. е. вызывая этот метод), есть ли потенциальные проблемы с использованием одного и другого?

+1

Вам нужно показать код, который вызывает 'UpdatePerson', также является' // получить из кеша и свойства update 'thread safe? Может ли он использоваться одновременно из нескольких потоков без проблем? Наконец, если свойство 'Name' не является объектом с автоматическим имплантированием, вам также нужно показать нам это. –

+0

Реализация кэша не является потокобезопасной. Однако для этой дискуссии предположим, что я написал в кеш до выполнения Parallel.for и никаких изменений не будет написано, между тем, имеет ли это значение? Чтение из кеша на основе уникального идентификатора и (зная, что все люди в списке различны) имеет значение? Поскольку одна задача получит значение для id 1. другой id 2 и т. Д. (В то же время, но разные идентификаторы) – ShaneKm

ответ

1

Оставим на минуту параллельная часть, что вы хотите сделать некоторые 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.

-2

Не имеет значения, каков ваш объект возврата. Параллель.For() будет работать одинаково в зависимости от того, как вы выполняете этот метод. если вы ожидаете возвращения Лица для его использования, то это не может потенциально замедлить ваше приложение, потому что оно не будет возвращать объект Person до тех пор, пока обновление не завершится.

Если возврат недействителен, некоторые другие части приложения не ожидают возвратного значения и теоретически должны работать нормально, независимо от того, когда произойдет обновление.

 Смежные вопросы

  • Нет связанных вопросов^_^