Герберт Шилдт - C# 4.0 полное руководство - 2011
- Название:C# 4.0 полное руководство - 2011
- Автор:
- Жанр:
- Издательство:неизвестно
- Год:неизвестен
- ISBN:нет данных
- Рейтинг:
- Избранное:Добавить в избранное
-
Отзывы:
-
Ваша оценка:
Герберт Шилдт - C# 4.0 полное руководство - 2011 краткое содержание
C# 4.0 полное руководство - 2011 - читать онлайн бесплатно полную версию (весь текст целиком)
Интервал:
Закладка:
Для работы с коллекцией типа BlockingCollection может оказаться полезным и метод CompleteAdding () . Ниже приведена форма его объявления.
public void CompleteAdding()
Вызов этого метода означает, что в коллекцию не будет больше добавлено ни одного элемента. Это приводит к тому, что свойство IsAddingComplete принимает логическое значение true. Если же коллекция пуста, то свойство IsCompleted принимает логическое значение true, и в этом случае вызовы метода Таке () не блокируются. Ниже приведены формы объявления свойств IsAddingComplete и IsCompleted.
public bool IsCompleted { get; } public bool IsAddingComplete { get; }
Когда коллекция типа BlockingCollection только начинает формироваться, эти свойства содержат логическое значение 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 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(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(); be.Dispose();
}
}
}
Этот вариант программы дает такой же результат, как и предыдущий. Главное его отличие заключается в том, что теперь метод Producer () может производить и поставлять сколько угодно элементов. С этой целью он просто вызывает метод CompleteAdding (), когда завершает создание элементов. А метод Consumer () лишь "потребляет" произведенные элементы до тех пор, пока свойство IsCompleted не примет логическое значение true.
Несмотря на специфический до некоторой степени характер параллельных коллекций, предназначенных в основном для параллельного программирования, у них, тем не менее, имеется немало общего с обычными, непараллельными коллекциями, описанными в предыдущих разделах. Если же вам приходится работать в среде параллельного программирования, то для организации одновременного доступа к данным из нескольких потоков вам, скорее всего, придется воспользоваться параллельными коллекциями.
Сохранение объектов, определяемых пользователем классов, в коллекции
Ради простоты приведенных выше примеров в коллекции, как правило, сохранялись объекты встроенных типов, в том числе int, string и char. Но ведь в коллекции можно хранить не только объекты встроенных типов. Достоинство коллекций в том и состоит, что в них допускается хранить объекты любого типа, включая объекты определяемых пользователем классов.
Рассмотрим сначала простой пример применения класса необобщенной коллекции ArrayList для хранения информации о товарных запасах. В этом классе инкапсулируется класс Inventory.
// Простой пример коллекции товарных запасов.
using System;
using System.Collections;
class Inventory { string name; double cost; int onhand;
public Inventory(string n, double c, int h) { name = n; cost = c; onhand = h;
}
public override string ToStringO { return
String.Format("{0,-10}Стоимость: {1,6:С} Наличие: {2}",
name, cost, onhand);
}
}
class InventoryList { static void Main() {
ArrayList inv = new ArrayList(); \
// Добавить элементы в список. inv.Add(new Inventory("Кусачки", 5.95, 3)); inv.Add(new Inventory("Отвертки", 8.29, 2)); inv.Add(new Inventory("Молотки", 3.50, 4)); inv.Add(new Inventory("Дрели", 19.88, 8));
Console.WriteLine("Перечень товарных запасов:"); foreach(Inventory i in inv) {
Console.WriteLine(" " + i);
При выполнении программы из данного примера получается следующий результат.
Перечень товарных запасов:
Обратите внимание на то, что в данном примере программы не потребовалось никаких специальных действий для сохранения в коллекции объектов типа Inventory. Благодаря тому что все типы наследуют от класса ob j ect, в необобщенной коллекции можно хранить объекты любого типа. Именно поэтому в необобщенной коллекции нетрудно сохранить объекты определяемых пользователем классов. Безусловно, это также означает, что такая коллекция не типизирована.
Для того чтобы сохранить объекты определяемых пользователем классов в типизированной коллекции, придется воспользоваться классами обобщенных коллекций. В качестве примера ниже приведен измененный вариант программы из предыдущего примера. В этом варианте используется класс обобщенной коллекции List, а результат получается таким же, как и прежде.
// Пример сохранения объектов класса Inventory в // обобщенной коллекции класса List.
using System;
using System.Collections.Generic;
class Inventory { string name; double cost; int onhand;
public Inventory(string n, double c, int h) { name = n; cost = c; onhand = h;
}
public override string ToString() { return
String.Format ("{0,-10}Стоимость: {1,6:С} Наличие: {2}", name, cost, onhand);
}
}
class TypeSafelnventoryList { static void Main() {
List inv = new List ();
// Добавить элементы в список. inv.Add(new Inventory("Кусачки", 5.95, 3)); inv.Add(new Inventory("Отвертки", 8.29, 2)); inv.Add(new Inventory("Молотки", 3.50, 4)); inv.Add(new Inventory("Дрели", 19.88, 8));
Console.WriteLine("Перечень товарных запасов:"); foreach(Inventory i in inv) {
Интервал:
Закладка: