Курс лекций для студентов специальности i-31 03 04 Информатика всех форм обучения Минск 2010


Коллекции, поддерживающие параллелизм



страница27/29
Дата09.08.2019
Размер0.64 Mb.
#126834
ТипКурс лекций
1   ...   21   22   23   24   25   26   27   28   29

Коллекции, поддерживающие параллелизм


Библиотека параллельных расширений содержит набор классов, представляющих коллекции с различным уровнем поддержки параллелизма. Указанные классы сосредоточены в пространстве имён System.Collections.Concurrent.

Класс BlockingCollection является реализацией шаблона «поставщик-потребитель»1. Этот класс реализует интерфейсы IEnumerable, ICollection, IDisposable, и имеет собственные элементы, описанные в табл. 21.

Таблица 21

Элементы класса BlockingCollection



Имя элемента

Описание

Add()

Добавляет элемент в коллекцию

AddToAny()

Статический метод, который добавляет элемент в любую из указанных BlockingCollection

CompleteAdding()

После вызова этого метода добавление элементов невозможно

GetConsumingEnumerable()

Возвращает перечислитель, который перебирает элементы с их одновременным удалением из коллекции

Take()

Получает элемент и удаляет его из коллекции. Если коллекция пуста, и у коллекции был вызван метод CompleteAdding(), генерируется исключение

TakeFromAny()

Статический метод, который получает элемент из любой указанной BlockingCollection

TryAdd()

Пытается добавить элемент в коллекцию, в случае успеха возвращает true. Дополнительно может быть задан временной интервал и токен отмены

TryAddToAny()

Статический метод, который пытается добавить элемент в любую из указанных коллекций

TryTake()

Пытается получить элемент (с удалением из коллекции), в случае успеха возвращает true

TryTakeFromAny()

Статический метод, который пытается получить элемент из любой указанной BlockingCollection

BoundedCapacity

Свойство возвращает максимальное число элементов, которое можно добавить в коллекцию без блокировки поставщика (данный параметр может быть указан при вызове конструктора BlockingCollection)

IsAddingCompleted

Возвращает true, если вызывался CompleteAdding()

IsCompleted

Возвращает true, если вызывался CompleteAdding() и коллекция пуста

Продемонстрируем работу с BlockingCollection, используя десять задач в качестве поставщика и одну в качестве потребителя:

BlockingCollection bc = new BlockingCollection();

for (int producer = 0; producer < 10; producer++)

{

Task.Factory.StartNew(() =>



{

Random rand = new Random();

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

{

Thread.Sleep(200);



bc.Add(rand.Next(100));

}

});



}
var consumer = Task.Factory.StartNew(() =>

{

foreach (var item in bc.GetConsumingEnumerable())



{

Console.WriteLine(item);

}

});


consumer.Wait();

Классы ConcurrentQueue, ConcurrentStack, ConcurrentBag и ConcurrentDictionary  это потокобезопасные классы для представления очереди, стека, неупорядоченного набора объектов и словаря. Предполагается, что данные классы будут использоваться в качестве разделяемых между потоками ресурсов вместо обычных классов-коллекций. Отличительная особенность данных коллекций – наличие Try-методов для получения (изменения) элементов. Такие методы удобны, так как исключают предварительные проверки существования и необходимость использования в клиентском коде секции lock.

// обычный стек Stack

T item;


if (stack.Count > 0) // проверяем наличие элементов

{

item = stack.Pop(); // затем извлекаем элемент



UseData(item);

}
// стек ConcurrentStack

T item;

if (concurrentStack.TryPop(out item)) // пытаемся извлечь элемент



{

UseData(item);

}

2.30. Асинхронный вызов методов


Платформа .NET содержит средства для поддержки асинхронного вызова методов. При асинхронном вызове поток выполнения разделяется на две части: в одной выполняется метод, а в другой – процесс программы. Асинхронный вызов служит альтернативой использованию многопоточности явным образом.

Асинхронный вызов всегда выполняется посредством объекта некоторого делегата. Любой такой объект содержит два специальных метода для асинхронных вызовов – BeginInvoke() и EndInvoke(). Эти методы генерируются во время выполнения программы, так как их сигнатура зависит от делегата1.

Метод BeginInvoke() обеспечивает асинхронный запуск. Кроме параметров, указанных при описании делегата, метод BeginInvoke() имеет два дополнительных параметра. Первый дополнительный параметр указывает на функцию завершения, выполняемую после окончания асинхронного метода. Второй дополнительный параметр – это объект, при помощи которого функции завершения может быть передана некоторая информация. Метод BeginInvoke() возвращает объект, реализующий интерфейс IAsyncResult. При помощи этого объекта становится возможным различать асинхронные вызовы одного и того же метода.

Приведём описание интерфейса IAsyncResult:

interface IAsyncResult

{

object AsyncState{ get; }



WaitHandle AsyncWaitHandle{ get; }

bool CompletedSynchronously{ get; }

bool IsCompleted{ get; }

}

Поле IsCompleted позволяет узнать, завершилась ли работа асинхронного метода. В поле AsyncWaitHandle хранится объект типа WaitHandle. Программист может вызывать методы объекта WaitHandle для контроля над потоком выполнения асинхронного метода. Объект AsyncState хранит последний аргумент, указанный при вызове BeginInvoke().



Делегат для функции завершения описан следующим образом:

public delegate void AsyncCallback(IAsyncResult ar);

Как видим, функции завершения передается единственный параметр  объект, реализующий интерфейс IAsyncResult.

Рассмотрим пример асинхронного вызова метода, который вычисляет и печатает факториал целого числа. Ни функции завершения, ни возвращаемое BeginInvoke() значение не используется. Подобный подход при работе с асинхронными методами называется «выстрелил и забыл» (fire and forget).

// создадим лямбду, чтобы вычислять факторал

Func factorial = null;

factorial = n => (n == 0) ? 1 : n * factorial(n - 1);
// создадим лямбду, чтобы печатать факторал

Action print = n => Console.WriteLine(factorial(n));


// запустим метод асинхроно, игнорируя дополнительные параметры

print.BeginInvoke(8000, null, null);


// эмулируем работу (результат увидим где-то на третьей итерации)

for (int i = 1; i < 10; i++)

{

Console.Write("Do some work...");



Thread.Sleep(1000);

}

Модифицируем предыдущий пример. Будем передавать в BeginInvoke() функцию завершения и дополнительный параметр.



// объект print не изменился

// функция завершения будет выводить время выполнения метода

AsyncCallback timer = ar =>

{

var dt = (DateTime) ar.AsyncState;



Console.WriteLine(DateTime.Now - dt);

};
print.BeginInvoke(8000, timer, DateTime.Now);

print.BeginInvoke(1000, timer, DateTime.Now);

В рассмотренных примерах использовались асинхронные методы, которые не возвращают значения. В приложении может возникнуть необходимость в асинхронных методах-функциях. Для получения результата работы асинхронной функции предназначен метод EndInvoke(). Параметры EndInvoke() определяется на основе параметров метода, инкапсулированного делегатом. Во-первых, EndInvoke() является функцией, тип которой совпадает с типом инкапсулируемого метода. Во-вторых, метод EndInvoke() содержит все out- и ref- параметры делегата, а последний параметр имеет тип IAsyncResult. При вызове метода EndInvoke() основной поток выполнения приостанавливается до завершения работы соответствующего асинхронного метода.

Изменим пример работы с асинхронными делегатами, превратив метод нахождения факториала в функцию:

// объект factorial определён в первом примере

// так как отслеживаем окончание работы методов,

// сохраняем результат вызова BeginInvoke()

IAsyncResult ar1 = factorial.BeginInvoke(8000, null, null);

IAsyncResult ar2 = factorial.BeginInvoke(1000, null, null);


Thread.Sleep(2000);

// получаем результат второго вызова и печатаем его

BigInteger res1 = factorial.EndInvoke(ar2);

Console.WriteLine(res1);


// получаем результат первого вызова

BigInteger res2 = factorial.EndInvoke(ar1);

Console.WriteLine(res2);

В заключение заметим, что технически асинхронный вызов методов реализуется средой исполнения при помощи пула потоков.



Каталог: images
images -> В списке студентов (или магистрантов)
images -> Н. И. Сулейманов Комплект контрольно-оценочных средств для оценки результатов освоения профессионального модуля разработан на основе Федерального государственного образовательного стандарта среднего профессионального
images -> По направлению подготовки
images -> Добавить гаджеты. Добавление гаджетов
images -> Техническое задание № apnip/C. 2/CS/Ind/01 Международный консультант по улучшенной производительности орошаемого земледелия
images -> Комплект контрольно-оценочных средств по профессиональному модулю пм. 01 Техническое обслуживание и ремонт автотранспорта


Поделитесь с Вашими друзьями:
1   ...   21   22   23   24   25   26   27   28   29




База данных защищена авторским правом ©vossta.ru 2022
обратиться к администрации

    Главная страница