Как создать без дубликатов ConcurrentQueue? - PullRequest
13 голосов
/ 01 мая 2011

Мне нужна параллельная коллекция, которая не допускает дублирования (для использования в BlockingCollection в качестве производителя / потребителя).Мне не нужен строгий порядок элементов.С другой стороны, я хочу минимизировать максимальное время "живого" элемента в коллекции.Т.е. коллекция не должна быть LIFO, в идеале она должна быть FIFO.

Хорошо, я бы сказала, что мне нужен ConcurrentQueue без дубликатов, но ConcurrentBag без дубликатов также может работать.

Почему C #не содержит ничего подобного, и, возможно, кто-то уже создал это?

Этот вопрос является результатом моего предыдущего вопроса Какой тип IProducerConsumerCollection использовать для моей задачи?

Ответы [ 3 ]

3 голосов
/ 03 октября 2011

Нет встроенных библиотек .Net, которые объединяют этот набор правил для коллекции.У вас есть три варианта:

  1. Написать свой собственный класс коллекции
  2. Использовать две коллекции: написать собственный класс, который использует один ConcurrentQueue, и любую коллекцию на основе множеств, которая автоматически проверяет наличие дубликатов;добавить в Set run и в случае успеха добавить в ConcurrentQueue;каждое добавление / удаление будет добавлено в обе коллекции при успешном
  3. Использовать ConcurrentQueue, но выполнять итерацию всего списка, проверяя наличие дубликата

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

1 голос
/ 01 мая 2011

Ну, если вы строго хотите, чтобы не было дубликатов, вам нужны «Наборы». Например, NHibernate использует Iesi.Collections для обеспечения такой функциональности. Используя Iesi, вы можете построить свою собственную функциональность вокруг предоставленных классов 'Set' (DictionarySet, HashSet, SortedSet). Источник: http://www.codeproject.com/KB/recipes/sets.aspx

0 голосов
/ 08 февраля 2012

Вы можете просто использовать ConcurrentQueue и перед вызовом Enqueue проверить, находятся ли данные в очереди, вызвав метод ConcurrentQueue.Contains<>. Я предполагаю, что метод расширения Contains<> довольно хорошо оптимизирован.

EDIT: Как уже отмечали другие, чтобы это работало, вам бы пришлось использовать механизм блокировки, такой как мьютекс и т. Д. Вокруг метода Contains<> и метода Enqueue, например:

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