Выполнение асинхронного вызова
Процедура синхронного вызова проста: клиент получает указатель интерфейса на объект сервера и вызывает методы с помощью этого указателя. Асинхронный вызов включает объект вызова, поэтому он включает несколько дополнительных шагов.
Для каждого метода в синхронном интерфейсе соответствующий асинхронный интерфейс реализует два метода. Эти методы присоединяют префиксы Begin_ и Finish_ к имени синхронного метода. Например, если интерфейс с именем ISimpleStream имеет метод Read, интерфейс AsyncISimpleStream будет иметь Begin_Read и метод Finish_Read. Чтобы начать асинхронный вызов, клиент вызывает метод Begin_.
Начало асинхронного вызова
Запросите объект сервера для интерфейса ICallFactory. Если QueryInterface возвращает E_NOINTERFACE, объект сервера не поддерживает асинхронный вызов.
Вызовите ICallFactory::CreateCall, чтобы создать объект вызова, соответствующий нужному интерфейсу, а затем освободить указатель на ICallFactory.
Если вы не запросили указатель на асинхронный интерфейс из вызова CreateCall, запросите объект вызова для асинхронного интерфейса.
Вызовите соответствующий метод Begin_.
Теперь серверный объект обрабатывает асинхронный вызов, и клиент может выполнять другие действия, пока он не нуждается в результатах вызова.
Объект вызова может обрабатывать только один асинхронный вызов за раз. Если тот же или второй клиент вызывает метод Begin_ до завершения ожидающего асинхронного вызова, метод Begin_ вернет RPC_E_CALL_PENDING.
Если клиенту не нужны результаты метода Begin_, он может освободить объект вызова в конце этой процедуры. COM обнаруживает это условие и очищает вызов. Метод Finish_ не вызывается, и клиент не получает никаких параметров или возвращаемого значения.
Когда объект сервера готов к возврату из метода Begin_, он сообщает объекту вызова, который он выполняет. Когда клиент готов, он проверка, чтобы узнать, был ли сигнал объекта вызова. В этом случае клиент может завершить асинхронный вызов.
Механизм для этого сигнала и проверка между клиентом и сервером — это интерфейс ISynchronize в объекте вызова. Объект вызова обычно реализует этот интерфейс путем агрегирования объекта синхронизации, предоставленного системой. Объект синхронизации упаковывает дескриптор событий, который сервер сигнализирует непосредственно перед возвращением из метода Begin_ путем вызова ISynchronize::Signal.
Завершение асинхронного вызова
Запрос объекта вызова для интерфейса ISynchronize.
Вызов ISynchronize ::Wait.
Если ожидание возвращает RPC_E_TIMEOUT, метод Begin_ не завершает обработку. Клиент может продолжить работу и снова вызвать ожидание позже. Он не может вызывать метод Finish_, пока ожидание не возвращает S_OK.
Если ожидание возвращает S_OK, метод Begin_ возвращается. Вызовите соответствующий метод Finish_.
Метод Finish_ передает клиенту любые параметры. Поведение асинхронных методов, включая возвращаемое значение метода Finish_, должно соответствовать точно тому, что соответствующего синхронного метода.
Клиент может освободить объект вызова, как только метод Finish_ возвращается, или он может содержать указатель на объект вызова для выполнения дополнительных вызовов. В любом случае клиент несет ответственность за освобождение объекта вызова, если объект больше не нужен.
При вызове метода Finish_ при отсутствии вызова метод вернет RPC_E_CALL_COMPLETE.
Примечание.
Если клиентские и серверные объекты находятся в одной квартире, вызовы ICallFactory::CreateCall не гарантированы успешно. Если объект сервера не поддерживает асинхронный вызов определенного интерфейса, попытка создания объекта вызова завершится ошибкой, и клиент должен использовать синхронный интерфейс.
См. также