Используйте Parallel.Foreach для обновления свойств сущности с безопасностью потока - PullRequest
0 голосов
/ 03 марта 2020

Я пытаюсь использовать Parallel.Foreach для обновления свойств объекта: обратитесь, как показано в примере кода

var contactIds = new List<int>();
contactIds.AddRange(res.RelatedContacts.Select(c => c.IdVal).ToList());
contacts = await _dbContext.Contacts.Where(co => contactIds.Contains(co.ContactId)).ProjectTo<ContactDTO>(_mapper.ConfigurationProvider).AsNoTracking().ToListAsync();

foreach (var contactrec in contacts)
{
    var contact = contacts.FirstOrDefault(c => c.ContactId.Equals(contactrec.ContactId));
    if (contact != null)
    {
        contact.address = addresses.FirstOrDefault(a => a.AddressId.Equals(contact.AddressId));
        contact.ImagePath = contact.ImageId > 0 ? images.FirstOrDefault(im => im.ImageId.Equals(contact.ImageId)).FilePath : "NA";
    }
}

Я хочу заменить приведенный выше код на Parallel.Foreach с безопасностью потока.

1 Ответ

1 голос
/ 08 марта 2020

Я согласен с комментариями, там есть некоторые запахи кода, и, вероятно, написание запроса более эффективным способом ускорит весь процесс в большей степени, чем любая оптимизация, полученная с помощью параллелизма.

Сказав это, я думаю, что вы ищете что-то вроде этого:

var contactIds = new List<int>();
contactIds.AddRange(res.RelatedContacts.Select(c => c.IdVal).ToList());
contacts = await _dbContext.Contacts.Where(co => contactIds.Contains(co.ContactId)).ProjectTo<ContactDTO>(_mapper.ConfigurationProvider).AsNoTracking().ToListAsync();

Parallel.Foreach(contacts, contact => Update(contact));
//or: Parallel.Foreach(contacts, Update);
void Update(Contact contact){
    contact.address = addresses.FirstOrDefault(a => a.AddressId.Equals(contact.AddressId));
    contact.ImagePath = contact.ImageId > 0 ? images.FirstOrDefault(im => im.ImageId.Equals(contact.ImageId)).FilePath : "NA";
}

Некоторые примечания:

  • нет необходимости повторять через идентификаторы, а затем получить первый элемент с этим идентификатором. Просто итерируйте элементы.
  • не должно быть проблем с безопасностью потока, операции в Update доступны только для чтения.
...