Читать «C# 4.0: полное руководство» онлайн - страница 631
Герберт Шилдт
ConcurrentQueue<T> - Реализует параллельную очередь и соответствующий вариант интерфейса IProducerConsumerCollection<T>
ConcurrentStack<T> - Реализует параллельный стек и соответствующий вариант интерфейса IproducerConsumerCollection<T>
Как видите, в нескольких классах параллельных коллекций реализуется интерфейс IProducerConsumerCollection
. Этот интерфейс также определен в пространстве имен System.Collections.Concurrent
. Он служит в качестве расширения интерфейсов IEnumerable, IEnumerable<T>
и ICollection
. Кроме того, в нем определены методы TryAdd()
и TryTake()
, поддерживающие шаблон "поставщик-потребитель". (Классический шаблон "поставщик-потребитель" отличается решением двух задач. Первая задача производит элементы коллекции, а другая потребляет их.) Метод TryAdd()
пытается добавить элемент в коллекцию, а метод TryTake()
— удалить элемент из коллекции. Ниже приведены формы объявления обоих методов.
bool TryAdd(Т item)
bool TryTake(out T item)
Метод TryAdd()
возвращает логическое значение true
, если в коллекцию добавлен элемент TryTake()
возвращает логическое значение true
, если элемент iTryAdd()
выполнен успешно, то элемент iIProducerConsumerCollection
указывается перегружаемый вариант метода CopyTo()
, определяемого в интерфейсе ICollection
, а также метода ТоАггау()
, копирующего коллекцию в массив.)
Параллельные коллекции зачастую применяются в комбинации с библиотекой распараллеливания задач (TPL) или языком PLINQ. В силу особого характера этих коллекций все их классы не будут рассматриваться далее подробно. Вместо этого на конкретных примерах будет дан краткий обзор класса BlockingCollection<T>
. Усвоив основы построения класса BlockingCollection<T>
, вы сможете без особого труда разобраться и в остальных классах параллельных коллекций.
В классе BlockingCollection<T>
, по существу, реализуется блокирующая очередь. Это означает, что в такой очереди автоматически устанавливается ожидание любых попыток вставить элемент в коллекцию, когда она заполнена, а также попыток удалить элемент из коллекции, когда она пуста. Это идеальное решение для тех ситуаций, которые связаны с применением шаблона "поставщик-потребитель". В классе BlockingCollection<T>
реализуются интерфейсы ICollection, IEnumerable, IEnumerable<T>
, а также IDisposable
.
В классе BlockingCollection<T>
определяются следующие конструкторы.
public BlockingCollection()
public BlockingCollection(int boundedCapacity)
public BlockingCollection(IProducerConsumerCollection<T> collection)
public BlockingCollection(IProducerConsumerCollection<T> collection,
int boundedCapacity)
В двух первых конструкторах в оболочку класса BlockingCollection<T>
заключается коллекция, являющаяся экземпляром объекта типа ConcurrentQueue<T>
. А в двух других конструкторах можно указать коллекцию, которая должна быть положена в основу коллекции типа BlockingCollection<T>
. Если указывается параметр