Kniga-Online.club
» » » » Герберт Шилдт - C# 4.0: полное руководство

Герберт Шилдт - C# 4.0: полное руководство

Читать бесплатно Герберт Шилдт - C# 4.0: полное руководство. Жанр: Программирование издательство -, год 2004. Так же читаем полные версии (весь текст) онлайн без регистрации и SMS на сайте kniga-online.club или прочесть краткое содержание, предисловие (аннотацию), описание и ознакомиться с отзывами (комментариями) о произведении.
Перейти на страницу:

Помимо методов TryAdd() и TryTake(), определяемых параллельно с теми, что указываются в интерфейсе IProducerConsumerCollection<T>, в классе BlockingCollection<T> определяется также ряд собственных методов. Ниже представлены методы, которые будут использоваться в приведенных далее примерах.

public void Add(T item)

public T Take()

Когда метод Add() вызывается для неограниченной коллекции, он добавляет элемент item в коллекцию и затем возвращает управление вызывающей части программы. А когда метод Add() вызывается для ограниченной коллекции, он блокирует доступ к ней, если она заполнена. После того как из коллекции будет удален один элемент или больше, указанный элемент item будет добавлен в коллекцию, и затем произойдет возврат из данного метода. Метод Таке() удаляет элемент из коллекции и возвращает управление вызывающей части программы. (Имеются также варианты обоих методов, принимающие в качестве параметра признак задачи как экземпляр объекта типа CancellationToken.)

Применяя методы Add() и Таке(), можно реализовать простой шаблон "поставщик-потребитель", как показано в приведенном ниже примере программы. В этой программе создается поставщик, формирующий символы от А до Z, а также потребитель, получающий эти символы. При этом создается коллекция типа BlockingCollection<T>, ограниченная 4 элементами.

// Простой пример коллекции типа BlockingCollection.

using System;

using System.Threading.Tasks;

using System.Threading;

using System.Collections.Concurrent;

class BlockingDemo {

  static BlockingCollection<char> bc;

  // Произвести и поставить символы от А до Z.

  static void Producer() {

    for(char ch = 'A'; ch <= 'Z'; ch++) {

      bc.Add(ch);

      Console.WriteLine ("Производится символ " + ch) ;

    }

  }

  // Потребить 26 символов,

  static void Consumer() {

    for(int i=0; i < 26; i++)

    Console .WriteLine ("Потребляется символ " + bc.Take());

  }

  static void Main() {

    // Использовать блокирующую коллекцию, ограниченную 4 элементами,

    bc = new BlockingCollection<char>(4);

    // Создать задачи поставщика и потребителя.

    Task Prod = new Task(Producer);

    Task Con = new Task(Consumer);

    // Запустить задачи.

    Con.Start();

    Prod.Start();

    // Ожидать завершения обеих задач,

    try {

      Task.WaitAll(Con, Prod);

    } catch(AggregateException exc) {

      Console.WriteLine (exc);

    } finally {

      Con.Dispose();

      Prod.Dispose();

      bc.Dispose();

    }

  }

}

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

Для работы с коллекцией типа 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> bc;

  // Произвести и поставить символы от А до Z.

  static void Producer() {

    for (char ch = 'A'; ch <= 'Z'; ch++) {

      bc.Add(ch);

      Console.WriteLine("Производится символ " + ch);

    }

    bc.CompleteAdding();

  }

  // Потреблять символы до тех пор, пока их будет производить поставщик.

  static void Consumer() {

    char ch;

    while(!bc.IsCompleted) {

      if(bc.TryTake(out ch))

        Console.WriteLine("Потребляется символ " + ch);

    }

  }

  static void Main() {

    // Использовать блокирующую коллекцию,

    // ограниченную 4 элементами,

    bc = new BlockingCollection<char>(4);

    // Создать задачи поставщика и потребителя.

    Task Prod = new Task(Producer);

    Task Con = new Task(Consumer);

    // Запустить задачи.

    Con.Start();

    Prod.Start();

    // Ожидать завершения обеих задач,

    try {

      Task.WaitAll(Con, Prod);

    } catch(AggregateException exc) {

      Console.WriteLine (exc);

    } finally {

      Con.Dispose();

      Prod.Dispose();

      bc.Dispose();

    }

  }

}

Этот вариант программы дает такой же результат, как и предыдущий. Главное его отличие заключается в том, что теперь метод Producer() может производить и поставлять сколько угодно элементов. С этой целью он просто вызывает метод CompleteAdding(), когда завершает создание элементов. А метод Consumer() лишь "потребляет" произведенные элементы до тех пор, пока свойство IsCompleted не примет логическое значение true.

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

Сохранение объектов, определяемых пользователем классов, в коллекции

Ради простоты приведенных выше примеров в коллекции, как правило, сохранялись объекты встроенных типов, в том числе int, string и char. Но ведь в коллекции можно хранить не только объекты встроенных типов. Достоинство коллекций в том и состоит, что в них допускается хранить объекты любого типа, включая объекты определяемых пользователем классов.

Рассмотрим сначала простой пример применения класса необобщенной коллекции ArrayList для хранения информации о товарных запасах. В этом классе инкапсулируется класс Inventory.

Перейти на страницу:

Герберт Шилдт читать все книги автора по порядку

Герберт Шилдт - все книги автора в одном месте читать по порядку полные версии на сайте онлайн библиотеки kniga-online.club.


C# 4.0: полное руководство отзывы

Отзывы читателей о книге C# 4.0: полное руководство, автор: Герберт Шилдт. Читайте комментарии и мнения людей о произведении.


Уважаемые читатели и просто посетители нашей библиотеки! Просим Вас придерживаться определенных правил при комментировании литературных произведений.

  • 1. Просьба отказаться от дискриминационных высказываний. Мы защищаем право наших читателей свободно выражать свою точку зрения. Вместе с тем мы не терпим агрессии. На сайте запрещено оставлять комментарий, который содержит унизительные высказывания или призывы к насилию по отношению к отдельным лицам или группам людей на основании их расы, этнического происхождения, вероисповедания, недееспособности, пола, возраста, статуса ветерана, касты или сексуальной ориентации.
  • 2. Просьба отказаться от оскорблений, угроз и запугиваний.
  • 3. Просьба отказаться от нецензурной лексики.
  • 4. Просьба вести себя максимально корректно как по отношению к авторам, так и по отношению к другим читателям и их комментариям.

Надеемся на Ваше понимание и благоразумие. С уважением, администратор kniga-online.


Прокомментировать
Подтвердите что вы не робот:*
Подтвердите что вы не робот:*