Ориентированное на многопотоковое исполнение foreach перечисление списков

11
задан Radu094 15 September 2008 в 20:29
поделиться

9 ответов

Клонирование списка является самым легким и лучшим способом, потому что это гарантирует, что Ваш список не изменится из-под Вас. Если список является просто слишком большим, чтобы клонировать, рассмотреть помещение блокировки вокруг этого, которая должна быть взята прежде, чем читать/писать в него.

13
ответ дан 3 December 2019 в 04:15
поделиться
ICollection MyCollection;
// Instantiate and populate the collection
lock(MyCollection.SyncRoot) {
  // Some operation on the collection, which is now thread safe.
}

Из MSDN

1
ответ дан 3 December 2019 в 04:15
поделиться

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

1
ответ дан 3 December 2019 в 04:15
поделиться

Нет такой операции. Лучшее, которое можно сделать,


lock(collection){
    foreach (object o in collection){
       ...
    }
}
2
ответ дан 3 December 2019 в 04:15
поделиться

Вы найдете, что это - очень интересная тема.

Лучший подход полагается на ReadWriteResourceLock, которые используют, чтобы иметь большие проблемы производительности из-за так называемой проблемы Конвоя.

Лучшая статья я нашел затрагивание темы, является этим Jeffrey Richter, который выставляет ее собственный метод для высокопроизводительного решения.

3
ответ дан 3 December 2019 в 04:15
поделиться

Ваша проблема состоит в том, что перечисление не позволяет IList изменяться. Это означает, что необходимо избежать этого при прохождении через списка.

Несколько возможностей приходят на ум:

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

С другой стороны, Вы могли записать свою собственную реализацию IList и IEnumerator, который позволяет вид параллельного доступа, в котором Вы нуждаетесь. Однако я боюсь, что это не будет просто.

3
ответ дан 3 December 2019 в 04:15
поделиться

Таким образом, требования: необходимо перечислить через IList <>, не делая копию при одновременном добавлении и удалении элементов.

Вы могли разъяснить несколько вещей? Вставки и удаления происходят только вначале или конец списка? Если модификации могут произойти в какой-либо точке в списке, как перечисление должно вести себя, когда элементы удалены или добавлены рядом или на местоположении элемента тока перечисления?

Это, конечно, выполнимо путем создания пользовательского объекта IEnumerable с, возможно, целочисленным индексом, но только если можно управлять всем доступом к IList <> объект (для блокировки и поддержания состояния перечисления). Но многопоточное программирование является хитрым бизнесом при самом удачном стечении обстоятельств, и это - комплекс probablem.

2
ответ дан 3 December 2019 в 04:15
поделиться

Перенесите список в объект блокировки для чтения и записи. Можно даже выполнить итерации с несколькими читателями сразу, если у Вас есть подходящая блокировка, которая позволяет несколько параллельных средств чтения, но также и единственное устройство записи (когда нет никаких читателей).

0
ответ дан 3 December 2019 в 04:15
поделиться

Default behavior for a simple indexed data structure like a linked list, b-tree, or hash table is to enumerate in order from the first to the last. It would not cause a problem to insert an element in the data structure after the iterator had already past that point or to insert one that the iterator would enumerate once it had arrived, and such an event could be detected by the application and handled if the application required it. To detect a change in the collection and throw an error during enumeration I could only imagine was someone's (bad) idea of doing what they thought the programmer would want. Indeed, Microsoft has fixed their collections to work correctly. They have called their shiny new unbroken collections ConcurrentCollections (System.Collections.Concurrent) in .NET 4.0.

1
ответ дан 3 December 2019 в 04:15
поделиться
Другие вопросы по тегам:

Похожие вопросы: