Con.Dispose ();
Prod.Dispose (); be.Dispose();
}
}
}
Если запустить эту программу на выполнение, то на экране появится смешанный результат, выводимый поставщиком и потребителем. Отчасти это объясняется тем, что коллекция Ьс ограничена 4 элементами, а это означает, что в нее может быть добавлено только четыре элемента, прежде чем ее придется сократить. В качестве эксперимента попробуйте сделать коллекцию Ьс неограниченной и понаблюдайте за полученными результатами. В некоторых средах выполнения это приведет к тому, что все элементы коллекции будут сформированы до того, как начнется какое-либо их потребление. Кроме того, попробуйте ограничить коллекцию одним элементом. В этом случае одновременно может быть сформирован лишь один элемент.
Для работы с коллекцией типа BlockingCollection<T> может оказаться полезным и метод CompleteAdding (). Ниже приведена форма его объявления.
public void CompleteAdding()
Вызов этого метода означает, что в коллекцию не будет больше добавлено ни одного элемента. Это приводит к тому, что свойство IsAddingComplete принимает логическое значение true. Если же коллекция пуста, то свойство IsCompleted принимает логическое значение true, и в этом случае вызовы метода Таке () не блокируются. Ниже приведены формы объявления свойств IsAddingComplete и IsCompleted.
public bool IsCompleted { get; } public bool IsAddingComplete { get; }
Когда коллекция типа BlockingCollection<T> только начинает формироваться, эти свойства содержат логическое значение false. А после вызова метода CompleteAdding () они принимают логическое значение true.
Ниже приведен вариант предыдущего примера программы, измененный с целью продемонстрировать применение метода CompleteAdding (), свойства IsCompleted и метода TryTake ().
// Применение методов CompleteAdding(), TryTake() и свойства IsCompleted. using System;
using System.Threading.Tasks;
using System.Threading;
using System.Collections.Concurrent;
class BlockingDemo {
static BlockingCollection<char> be;
// Произвести и поставить символы от А до Z. static void Producer() {
for (char ch = 'A'; ch <= 'Z'; ch++) { be.Add(ch);
Console.WriteLine('Производится символ ' + ch);
}
be.CompleteAdding();
}
// Потреблять символы до тех пор, пока их будет производить поставщик.
static void Consumer() {
char ch;
while(!be.IsCompleted) { if(be.TryTake(out ch))
Console.WriteLine('Потребляется символ ' + ch);
}
}
static void Main() {
// Использовать блокирующую коллекцию, ограниченную 4 элементами, be = new BlockingCollection<char>(4);
// Создать задачи поставщика и потребителя.
Task Prod = new Task(Producer);
Task Con = new Task(Consumer);
// Запустить задачи.
Con.Start();
