Периодически перебирая коллекцию, которая постоянно меняется - PullRequest
3 голосов
/ 04 мая 2010

У меня есть коллекция объектов, которая постоянно меняется, и я хочу отображать некоторую информацию о содержимом очень часто (мое приложение является многопоточным, и по-разному потоки постоянно отправляют запросы на изменение объекта в коллекции, поэтомуэто непредсказуемо).

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

  • Сделайте копию коллекции и выполните итерации по ней, что позволит оригиналу продолжить обновление в фоновом режиме.Коллекция может стать большой, поэтому это не идеально, но это безопасно.
  • Выполните итерацию по ней с помощью цикла For ... Next и поймайте исключение IndexOutOfBounds, если элемент удален из коллекции, пока мыповторяем.Это может иногда приводить к появлению дубликатов в моем снимке, так что это тоже не идеально.

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

Ответы [ 3 ]

2 голосов
/ 04 мая 2010

Возможно, вы захотите использовать некоторые одновременные коллекции из пространства имен System.Concurrent, если используете .NET Framework 4. Например, итераторы, возвращаемые из класса ConcurrentQueue<T>, представляют момент времени просмотр коллекции и не зависит от изменения в коллекции. Обычный итераторы коллекции будут признаны недействительными из-за изменений в базовой коллекции. В противном случае у вас нет выбора, кроме как сначала заблокировать коллекцию. Может быть, есть сторонние реализации параллельных коллекций. Но я не смотрел в те. Вот информация о поточно-ориентированных коллекциях в .NET Framework 4.

http://msdn.microsoft.com/en-us/library/dd997305(v=VS.100).aspx

1 голос
/ 04 мая 2010

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

0 голосов
/ 04 мая 2010

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

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

http://www.cs.tau.ac.il/~shanir/concurrent-data-structures.pdf

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