Чтение онлайн

на главную - закладки

Жанры

Шрифт:

public class SomeAsyncController : AsyncController

{

...

}

После этого конструктор по умолчанию, унаследованный от AsyncController, определит новый вариант ActionInvoker в виде экземпляра класса AsyncControllerActionInvoker для того, чтобы выполнять асинхронные действия. Для реализации асинхронных действий механизм AsyncController предлагает три паттерна, которые вы вольны использовать по отдельности либо смешивать их друг с другом: IAsyncResult, Event, Delegate.

Паттерн IAsyncResult

Паттерн IAsyncResult предполагает, что разработчик сам создаст асинхронную операцию. Согласно этому паттерну, вместо одного метода действия с именем XXX создаются два метода, BeginXXX и EndXXX, со следующим определением параметров:

public IAsyncResult BeginXXX(Guid? userId, AsyncCallback callback, object state);

public ActionResult EndXXX(IAsyncResult asyncResult);

Этот паттерн работает следующим образом:

1. MVC принимает запрос на выполнение действия xxx.

2. Механизмы MVC и AsyncController вызовут BeginXXX точно так же, как и любое другое синхронное действие.

3. Предполагается, что метод Beginxxx создаст некую тяжеловесную асинхронную операцию, например файловое чтение или запрос к базе данных, и использует переданную через параметры функцию обратного вызова callback для вызова после завершения асинхронной операции.

4. После выполнения асинхронной операции будет вызван второй метод Endxxx, которому будет передан результат выполнения Beginxxx в виде экземпляра IAsyncResult.

5. Метод Beginxxx, используя данные, полученные от Beginxxx, формирует обычный для всех действий результат в виде ActionResult или его производных.

Паттерн Event

Согласно этому паттерну, метод действия разделяется на два метода: запуска и завершения:

public void XXX(Guid? userId);

public ActionResult XXXCompleted(...);

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

1. MVC принимает запрос на выполнение действия xxx.

2. Механизмы MVC и AsyncController вызовут XXX точно так же, как и любое другое синхронное действие.

3. Разработчик определяет внутри метода xxx асинхронную операцию, после запуска которой метод завершает свое выполнение.

4. Чтобы механизм асинхронных контроллеров мог определить, когда следует вызвать XXXCompleted, разработчик должен воспользоваться свойством AsyncManager.OutstandingOperations, которое является стандартным для класса контроллера AsyncController.

5. Разработчик инкрементирует AsyncManager.OutstandingOperations при создании каждого асинхронного процесса и заботится о том, чтобы по завершению процесса свойство AsyncManager.OutstandingOperations было декрементировано.

6. Механизм AcyncControllerActionInvoker следит за свойством AsyncManager.OutstandingOperations и вызывает XXXCompleted, когда это свойство обнулится, что означает завершение работы всех асинхронных процессов.

7. Параметры для XXXCompleted определяет разработчик. Для того

чтобы AcyncControllerActionInvoker мог правильно выполнить XXXCompleted и передать необходимые параметры, разработчик заполняет специальную структуру AsyncManager.Parameters, которая является частью класса AsyncController. Структура AsyncManager.Parameters заполняется при работе метода xxx.

8. После завершения работы XXX механизм AcyncControllerActionInvoker вызывает метод XXXCompleted с набором параметров на базе AsyncManager.Parameters.

9. Используя переданные параметры, метод XXXCompleted возвращает стандартный результат в виде ActionResult или его производных.

Следующий фрагмент кода демонстрирует реализацию паттерна Event:

public void SelectUser(Guid? userId)

{

AsyncManager.Parameters["userData''] = new UserData;

AsyncManager.OutstandingOperations.Increment;

ThreadPool.QueueUserWorkItem(o =>

{

Thread.Sleep(2000);

AsyncManager.OutstandingOperations.Decrement;

}, null);

}

public ActionResult SelectUserCompleted(UserData userData)

{

...

}

Чтобы упростить процесс, существует альтернатива прямому инкрементированию и декрементированию. С помощью стандартной части AsyncController метода AsyncManager.RegisterTask можно использовать связку из паттернов IAsyncResult и Event. Рассмотрим на примере:

public void XXX(Guid? userId)

{

AsyncManager.RegisterTask(

callback => BeginXXX(userId, callback, null),

asyncResult =>

{

UserData userData = EndXXX(asyncResult);

AsyncManager.Parameters["userData"] = userData;

}

);

}

public ActionResult XXXCompleted(UserData userData)

{

// ...

}

Во фрагменте кода используется паттерн Event, согласно которому создается два метода: xxx и xxxCompleted. Метод xxx регистрирует асинхронную задачу с помощью механизма AsyncManager.RegisterTask, который принимает два параметра: анонимные функции, осуществляющие логику паттерна IAsyncResult. Первая функция вызывает метод Beginxxx, который выполняет некую асинхронную операцию. Вторая анонимная функция выполняется тогда, когда асинхронная операция заканчивается и ей передаются результаты вызова Beginxxx. Задача второй анонимной функции состоит в том, чтобы, используя метод Endxxx паттерна IAsyncResult, получить значения параметров для метода XXXCompleted.

Преимущество данной связки паттернов состоит в том, что разработчику предоставляется возможность создавать несколько следующих подряд вызовов механизма AsyncManager.RegisterTask, которые выполняют разные асинхронные операции и формируют результаты разных параметров для метода XXXCompleted. Так как механизм AsyncManager.RegisterTask самостоятельно отслеживает инкремент и декремент свойства AsyncManager.OutstandingOperations, разработчику предлагается более безопасный и простой механизм создания нескольких асинхронных операций в одном запросе.

Поделиться:
Популярные книги

"Фантастика 2023-201. Компиляция. Книги 1-26

Кароль Елена
Фантастика 2023. Компиляция
Фантастика:
боевая фантастика
попаданцы
5.00
рейтинг книги
Фантастика 2023-201. Компиляция. Книги 1-26

Ожоги сердца (сборник)

Падерин Иван Григорьевич
Проза:
военная проза
советская классическая проза
5.00
рейтинг книги
Ожоги сердца (сборник)

Искры

Соколов Михаил
Проза:
советская классическая проза
5.00
рейтинг книги
Искры

Древние тайны (Сборник)

Булычев Кир
Алиса и ее друзья в лабиринтах истории
Детские:
детская фантастика
6.00
рейтинг книги
Древние тайны (Сборник)

Франклин Рузвельт. Человек и политик (с иллюстрациями)

Бернс Джеймс Макгрегор
Проза:
историческая проза
6.25
рейтинг книги
Франклин Рузвельт. Человек и политик (с иллюстрациями)

Академия

Сай Ярослав
2. Медорфенов
Фантастика:
юмористическая фантастика
попаданцы
аниме
5.00
рейтинг книги
Академия

Огненный шар. Повести и рассказы

Немцов Владимир Иванович
Фантастика:
научная фантастика
7.00
рейтинг книги
Огненный шар. Повести и рассказы

Тетралогия Будущего

Хайнлайн Роберт Энсон
Шедевры фантастики
Фантастика:
боевая фантастика
юмористическая фантастика
7.73
рейтинг книги
Тетралогия Будущего

Сан-Феличе. Книга вторая

Дюма-отец Александр
Приключения:
исторические приключения
6.00
рейтинг книги
Сан-Феличе. Книга вторая

Трилогия «Двуединый»

Сазанов Владимир Валерьевич
Фантастика:
фэнтези
6.12
рейтинг книги
Трилогия «Двуединый»

Светоносец. Трилогия

Джонсон Оливер
Светоносец
Фантастика:
фэнтези
5.00
рейтинг книги
Светоносец. Трилогия

Весь Дэн Браун в одном томе

Браун Дэн
Детективы:
триллеры
прочие детективы
5.00
рейтинг книги
Весь Дэн Браун в одном томе

Гражданский кодекс Российской Федерации. Части первая, вторая, третья и четвертая. Текст с изменения

коллектив авторов 1
Справочная литература:
путеводители
5.00
рейтинг книги
Гражданский кодекс Российской Федерации. Части первая, вторая, третья и четвертая. Текст с изменения

Географ глобус пропил. Золото бунта

Иванов Алексей Викторович
Проза:
современная проза
7.86
рейтинг книги
Географ глобус пропил. Золото бунта