Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Экзамен в гаи redacted.doc
Скачиваний:
5
Добавлен:
27.09.2019
Размер:
676.35 Кб
Скачать

2.Особенности итераторов в ccr. Итераторы

Ключевое понятие для CCR – итератор, который допускает последовательное выполнение кода без блокировки выполняющегося потока, в случае если итератор ожидает получения сообщения. Когда действие должно быть выполнено, что должно занять неопределенное количество времени, итератор запоминает текущую позицию в коде, и затем отдаёт управление, до тех пор, пока не будет получено сообщение. После получения сообщения код продолжает выполнение из точки, где он был прерван.

Итераторы были представлены C# в версии 2.0, для поддержки foreach итераций, без необходимости реализации интерфейса IEnumerable. Каждый вызов итератора выполняет возвращение очередной величины в последовательности с использованием оператора yield return или завершение итерации с использованием yield break.

CCR использует итераторы, обрабатывающие последовательности задач, позволяя писать код, который выглядит похожим на последовательно выполняющийся, но в действительности представляющий собой последовательность асинхронных шагов. Итератор объявляется как метод типа IEnumerator <ITask>, что означает, что он будет взаимодействовать с задачами. Компилятор также допускает, что этот тип методов может содержать yield break и yield return утверждения, которые не могут быть использованы в обычном коде.

В случае IEnumerator <ITask> функция объявляется как перечислитель, который возвращает объекты типа <ITask>. Также могут быть созданы перечислители, которые возвращают различные типы, но задачи должны использоваться только в MRDS.

Итератор обозначается как метод типа IEnumerator<ITask>, что означает итерирование по задачам. Итераторы позволяют последовательно выполнять код без блокировки потока при ожидании сообщения. Когда операция будет завершена за неизвестное количество времени, итератор запоминает текущую позицию выполнения кода и оставляет управление до получения сообщения. В CCR итераторы основаны на последовательности задач, что позволяет писать код, который выглядит как последовательный, а в действительности представляет собой серию асинхронных шагов.

Создание итератора. Создадим метод со следующей сигнатурой:

public static IEnumerator<ITask> MyIterator()

//Создадим два порта принимающих значения int, используя следующее определение:

Port<int> p1 = new Port<int>();

//Пошлем на порт 1 значение 0

p1.Post(0);

//Введем булевскую переменную обозначающую конец цикла

bool done = false;

//Создадим цикл while (!done), в котором получатель сообщения одного порта посылает сообщение другому, испльзуя анонимный делегат

yield return Arbiter.Receive(false, p1, delegate(int i)

{

Console.WriteLine("P1 Thread {0}: {1}", Thread.CurrentThread.ManagedThreadId,i);

p2.Post(i + 1);

}

);

//Аналогично, задаим обработку сообщения на втором порту

yield return Arbiter.Receive(false, p2, delegate(int i)

{

Console.WriteLine("P2 Thread {0}: {1}", Thread.CurrentThread.ManagedThreadId,i);

if (i >= 10) done = true;

else p1.Post(i + 1);

}

);

Запуск итератора.

void RunFromIterator()

{

Dispatcher d = new Dispatcher(4, "Test Pool");

DispatcherQueue taskQ = new DispatcherQueue("Test Queue", d);

Console.WriteLine("Before Iterator submitted - thread {0}",

Thread.CurrentThread.ManagedThreadId);

Arbiter.Activate(taskQ,

Arbiter.FromIteratorHandler(IteratorExample),

Arbiter.FromIteratorHandler(IteratorExample));

Console.WriteLine("After Iterator submitted - thread {0}",

Thread.CurrentThread.ManagedThreadId);

}