Безопасно ли одновременно обращаться к нескольким индексам C # List <T>? - PullRequest
2 голосов
/ 26 марта 2019

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

Код выглядит следующим образом:

Parallel.For(0, pointsList.Count(), i=> pointsList[i] = DoThing(pointsList[i]));

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

Я думаю, что это нормально, но я подумал, что должен проверить: все ли в порядке, как есть, или мне нужно где-нибудь использовать Lock, опасаясь, что яиспортить список объектов ??

1 Ответ

4 голосов
/ 26 марта 2019

Безопасность не гарантируется. Изменение элемента в списке увеличивает частное поле списка _version, которое позволяет различным потокам определить, был ли список изменен. Если какой-либо другой поток попытается перечислить список или использует метод, подобный List<T>.ForEach(), то потенциально может возникнуть проблема. Звучит так, как будто это было бы крайне редко, что не обязательно хорошо, на самом деле это делает самый сводящий с ума тип дефекта.

Если вы хотите быть в безопасности, создайте новый список вместо изменения существующего. Это распространенный «функциональный» подход к проблемам потоков, который позволяет избежать блокировок.

var newList = pointsList.AsParallel().Select( item => DoThing(item) );

Когда вы закончите, вы всегда можете заменить старый список, если хотите.

pointsList = newList.ToList();
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...