Выполнение и обработка асинхронных вызовов

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

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

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

Примечание

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

 

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

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

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

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

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

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

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