Architecture Net



         

Использование делегатов в асинхронном программировании - часть 2


Вызов (invoke) начала (Begin) и конца (End)

При объявлении делегата компилятор генерирует класс с тремя методами: Beginlnvoke, Endlnvoke и Invoke (Вызвать). Beginlnvoke и Endlnvoke — методы с типовой безопасностью. Они соответствуют методам BeginXXX и EndXXX и позволяют вызывать делегат асинхронно. При вызове делегата компилятор использует метод Invoke (Вызвать)27. Чтобы асинхронно вызвать RegisterCustomer, достаточно использовать только методы Beginlnvoke и Endlnvoke.

RegisterCustomerCbk *rcc = new RegisterCustomerCbk(
customers, // клиенты
Customers::RegisterCustomer); // Клиенты for(int i = 1; i < 5; i++) {
firstName = String::Concat( // Строка
"FirstName", i.ToString ());
lastName = String::Concat( // Строка
"SecondName", (i * 2).ToString{));
emailAddress = String::Concat ( // Строка
i.ToString(), ".biz"); lAsyncResult *ar =
rcc->Begin!nvoke( firstName, lastName, emailAddress, 0, 0) ;
while(!ar->IsCompleted)
{
Console::WriteLine(
"Could do some work here while waiting for customer


registration to complete.");
// "Могу сделать некоторую работу здесь
//во время ожидания
// завершения регистрации клиента.");
ar->AsyncWaitHandle->WaitOne(1, false);
}
customerld = rcc->End!nvoke(ar) ;
Console::WriteLine(
Added Customerld: {0}",
// " Добавлен Customerld: {0}"
customerId.ToString());
}

Программа периодически ждет AsyncWaitHandle, чтобы увидеть, закончилась или нет регистрация. Если нет, то тем временем программа могла бы выполнить некоторую работу. Если Endlnvoke вызывается до завершения RegisterCustomer, то выполнение блокируется до завершения RegisterCustomer.

Асинхронный обратный вызов

Вместо ожидания на дескрипторе, можно передать функцию обратного вызова в Beginlnvoke (или BeginXXX) метод. Именно так и делается в примере AsynchWithCallback (Asynch с обратным вызовом).

RegisterCustomerCbk *rcc = new RegisterCustomerCbk( customers, // клиенты
Customers::RegisterCustomer);
// Клиенты AsyncCallback *cb =
new AsyncCallback(this, CustomerCallback);
Object *objectState; // Объект
JAsyncResult *ar; forUnt i = 5; i < 10; i++) {
firstName = String::Concat( // Строка
"FirstName", i.ToString());
lastName = String::Concat( // Строка
"SecondName", (i * 2).ToString());
emailAddress =
String::Concat(i.ToString(), ".biz"); // Строка
objectState = _box(i);
ar = rcc->Begin!nvoke( firstName,
lastName,
emailAddress,
cb,
objectState);
}
Console::WriteLine(
"Finished registrations...
could do some work here.");
// "Закончена регистрация... могу сделать
// некоторую работу здесь."
Thread::Sleep(25); // Поток:: Бездействие
Console::WriteLine(
"Finished work..waiting to let registrations complete.");


// "Закончена работа., жду конца регистрации.");
Thread::Sleep(1000); // Поток:: Бездействие

Потом мы получаем результат в функции обратного вызова:

void CustomerCallback(lAsyncResult *ar)
{
int customerld;
AsyncResult *asyncResult =
dynamic_cast<AsyncResult *>(ar);
RegisterCustomerCbk *rcc =
dynamic_cast<RegisterCustoraerCbk *> (asyncResult->AsyncDelegate);


customerld = rcc->EndInvoke(ar);
Console::WriteLine(
AsyncState: {0} Customerld {1} added.",
ar->AsyncState, customerld.ToString() ) ;
Console::WriteLine(
" Could do processing here.");
// " Могу сделать обработку здесь."
return;
}

В этом варианте можно выполнить некоторые действия до завершения регистрации каждого клиента.

CompEbook.ru Железо, дизайн, обучение и другие




Содержание  Назад  Вперед