Добавить в цитаты Настройки чтения

Страница 474 из 502

<b>        Console.WriteLine(&quot;Потребляется символ &quot; + ch);</b>

<b>    }</b>

<b>  }</b>

<b>  static void Main() {</b>

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

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

<b>    bc = new BlockingCollection&lt;char&gt;(4);</b>

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

<b>    Task Prod = new Task(Producer);</b>

<b>    Task Con = new Task(Consumer);</b>

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

<b>    Con.Start();</b>

<b>    Prod.Start();</b>

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

<b>    try {</b>

<b>      Task.WaitAll(Con, Prod);</b>

<b>    } catch(AggregateException exc) {</b>

<b>      Console.WriteLine (exc);</b>

<b>    } finally {</b>

<b>      Con.Dispose();</b>

<b>      Prod.Dispose();</b>

<b>      bc.Dispose();</b>

<b>    }</b>

<b>  }</b>

<b>}</b>

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

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

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

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

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

<b>// Простой пример коллекции товарных запасов.</b>

<b>using System;</b>

<b>using System.Collections;</b>

<b>class Inventory {</b>

<b>  string name;</b>

<b>  double cost;</b>

<b>  int onhand;</b>

<b>  public Inventory(string n, double c, int h) {</b>

<b>    name = n;</b>

<b>    cost = c;</b>

<b>    onhand = h;</b>

<b>  }</b>

<b>  public override string ToString() {</b>

<b>    return</b>

<b>        String.Format(&quot;{0,-10}Стоимость: {1,6:C} Наличие: {2}&quot;,</b>

<b>            name, cost, onhand);</b>

<b>  }</b>

<b>}</b>

<b>class InventoryList {</b>

<b>  static void Main() {</b>

<b>    ArrayList inv = new ArrayList();</b>

<b>    // Добавить элементы в список.</b>

<b>    inv.Add(new Inventory(&quot;Кусачки&quot;, 5.95, 3));</b>

<b>    inv.Add(new Inventory(&quot;Отвертки&quot;, 8.29, 2));</b>

<b>    inv.Add(new Inventory(&quot;Молотки&quot;, 3.50, 4));</b>

<b>    inv.Add(new Inventory(&quot;Дрели&quot;, 19.88, 8));</b>

<b>    Console.WriteLine(&quot;Перечень товарных запасов:&quot;);</b>

<b>    foreach(Inventory i in inv) {</b>

<b>      Console.WriteLine(&quot; &quot; + i);</b>

<b>    }</b>

<b>  }</b>

<b>}</b>

При выполнении программы из данного примера получается следующий результат.

<b>Перечень товарных запасов:</b>

<b> Кусачки   Стоимость:  $5,95 Наличие: 3</b>