Создание и обработка асинхронных вызовов

COM-объекты могут поддерживать асинхронные вызовы. Когда клиент выполняет асинхронный вызов, управление немедленно возвращается клиенту. Хотя сервер обрабатывает вызов, клиент может выполнять другие действия. Если клиент больше не может продолжаться без результатов вызова, он может получить результаты звонка в то время.

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

Клиенты не выполняют асинхронные вызовы непосредственно на серверном объекте. Вместо этого они получают объект вызова, реализующий асинхронную версию синхронного интерфейса на серверном объекте. Асинхронный интерфейс объекта вызова имеет имя формы AsyncInterfaceName. Например, если объект сервера реализует синхронный интерфейс с именем IMyInterface, будет объект вызова, реализующий асинхронный интерфейс с именем AsyncIMyInterface.

Примечание.

Асинхронная поддержка недоступна для IDispatch или интерфейсов, наследующих IDispatch.

 

Серверные объекты, поддерживающие асинхронные вызовы, реализуют интерфейс ICallFactory. Этот интерфейс предоставляет один метод CreateCall, который создает экземпляр указанного объекта вызова. Клиенты могут запрашивать ICallFactory, чтобы определить, поддерживает ли объект асинхронный вызов.

Для каждого метода в синхронном интерфейсе соответствующий асинхронный интерфейс реализует два метода. Эти методы присоединяют префиксы Begin_ и Finish_ к имени синхронного метода. Например, если интерфейс с именем ISimpleStream имеет метод Read, интерфейс AsyncISimpleStream будет иметь Begin_Read и метод Finish_Read. Чтобы начать асинхронный вызов, клиент вызывает метод Begin_.

При реализации серверного объекта не требуется предоставлять объект вызова для каждого интерфейса, реализуемого объектом. Если серверный объект реализует интерфейс ICallFactory и использует стандартное маршалинг, маршалированные клиенты всегда могут получить объект вызова прокси-сервера, даже если на стороне сервера нет объекта вызова. Этот прокси-сервер маршализировал метод Begin_ в виде синхронного вызова, сервер будет обрабатывать вызов синхронно, и клиент может получить параметры выхода, вызвав метод Finish_.

И наоборот, если клиент выполняет маршализированный синхронный вызов в интерфейсе, для которого на стороне сервера есть объект вызова, сервер всегда обрабатывает вызов асинхронно. Это поведение не будет очевидно для клиента, так как клиент получит те же параметры и то же возвращаемое значение, которое было бы получено от синхронного метода.

В любом случае взаимодействие между клиентом и сервером маршалируется так же, как если бы вызов был синхронным: выходные данные синхронных и асинхронных прокси-серверов неразличимы, как и выходные данные соответствующих заглушки. Это поведение значительно упрощает модель программирования как клиентов, так и серверов. Если серверный объект реализует ICallFactory, маршалированные клиенты не должны пытаться создать объект вызова, который может быть недоступен — клиенту, объект вызова всегда доступен.

Когда клиент и сервер находятся в одной квартире, объект сервера будет обрабатывать любой вызов клиента. Если объект вызова недоступен, клиент должен явно получить синхронный интерфейс и выполнить синхронный вызов.

Дополнительные сведения см. в следующих разделах: