2010-05-04 2 views
3

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

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

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

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

+0

Могу ли я получить объяснение downvote? – SqlRyan

+0

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

ответ

2

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

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

+0

Я не знал, что эти новые типы коллекций существуют - ConcurrentBag (Of ​​T) может быть именно тем, что я ищу. Спасибо за ссылку. – SqlRyan

1

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

+0

Я не приурочил операцию копирования, чтобы увидеть, будет ли это узким местом, но я решил, что это будет так, потому что мне нужно только несколько свойств от каждого объекта, но объекты могут быть сложными и многослойными (они содержат сами коллекции). Тем не менее, я сделаю некоторое тестирование и посмотрю, достаточно ли .ToArray, чтобы решить мою проблему. – SqlRyan

+0

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

+0

Похоже, вам не нужна глубокая копия, поэтому ToArray должен быть очень быстрым для вас, поскольку он делает только копии ссылок на объекты. –

0

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

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

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

+0

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

Смежные вопросы