Страницы

Поиск по вопросам

четверг, 4 апреля 2019 г.

Прогон в foreach с изменением количества элементов

У меня есть список. Необходимо прогнать все его элементы, вызвать в каждой итерации функцию расчета и при каком-то условии, удалить элемент из цикла и продолжить итерации.
Вначале думал про for и если удаляем, делать i--, т.к. уменьшилось количество элементов на 1, но это не сделать при параллельном прогоне, поэтому думаю сделать подобное в foreach, чтобы не привязываться к индексу элемента. Но при изменение foreach выскакивает исключение, что логично.
Можно ли как-нибудь прогнать параллельно по циклу и по условию, если что удалить элемент. Чтобы это не сказывалась на других элементах в параллельных потоках?


Ответ

Если удалять элемент из коллекции сразу же на месте не требуется — заведите еще одну (потокобезопасную) коллекцию, элементы подлежащие удалению складывайте в нее, после завершения первого цикла просто удалите из первой коллекции все элементы, присутствующие во второй:
// заводим коллекцию var forRemoving = new ConcurrentBag(); foreach (var item in items) { ... // складываем в нее элементы подлежащие удалению forRemoving.Add(item); } // удаляем foreach (var item in forRemoving) items.Remove(item);

Если для вашей задачи не принципиально удаление элементов из входной коллекции, а подойдет также вариант с формированием новой коллекцией — можно воспользоваться функционалом Parallel Linq:
var result = items.AsParallel() .Where(item => condition(item)) .ToList();

Комментариев нет:

Отправить комментарий