Fazendo e processando chamadas assíncronas

Objetos COM podem dar suporte a chamadas assíncronas. Quando um cliente faz uma chamada assíncrona, o controle retorna imediatamente ao cliente. Enquanto o servidor processa a chamada, o cliente é livre para fazer outro trabalho. Quando o cliente não pode mais prosseguir sem os resultados da chamada, ele pode obter os resultados da chamada no momento.

Por exemplo, uma solicitação para um conjunto de registros grande ou complexo pode ser demorada. Um cliente pode solicitar o conjunto de registros por uma chamada assíncrona e, em seguida, fazer outro trabalho. Quando o conjunto de registros está disponível, o cliente pode obtê-lo rapidamente sem bloquear.

Os clientes não fazem chamadas assíncronas diretamente no objeto do servidor. Em vez disso, eles obtêm um objeto de chamada que implementa uma versão assíncrona de uma interface síncrona no objeto do servidor. A interface assíncrona no objeto de chamada tem um nome do formulário AsyncInterfaceName. Por exemplo, se um objeto de servidor implementar uma interface síncrona chamada IMyInterface, haverá um objeto de chamada que implementa uma interface assíncrona chamada AsyncIMyInterface.

Observação

O suporte assíncrono não está disponível para IDispatch ou para interfaces que herdam IDispatch.

 

Objetos de servidor que dão suporte a chamadas assíncronas implementam a interface ICallFactory . Essa interface expõe um único método, CreateCall, que cria uma instância de um objeto de chamada especificado. Os clientes podem consultar iCallFactory para determinar se um objeto dá suporte a chamadas assíncronas.

Para cada método em uma interface síncrona, a interface assíncrona correspondente implementa dois métodos. Esses métodos anexam os prefixos Begin_ e Finish_ ao nome do método síncrono. Por exemplo, se uma interface chamada ISimpleStream tiver um método read, a interface AsyncISimpleStream terá um Begin_Read e um método Finish_Read. Para iniciar uma chamada assíncrona, o cliente chama o método Begin_.

Ao implementar um objeto de servidor, você não precisa fornecer um objeto de chamada para cada interface implementada pelo objeto. Se o objeto de servidor implementar a interface ICallFactory e usar o marshaling padrão, um cliente marshaled sempre poderá obter um objeto de chamada proxy, mesmo que não haja nenhum objeto de chamada no lado do servidor. Esse proxy fará marshaling do método Begin_ como uma chamada síncrona, o servidor processará a chamada de forma síncrona e o cliente poderá obter os parâmetros de saída chamando o método Finish_.

Por outro lado, se um cliente fizer uma chamada síncrona marshalada em uma interface para a qual há um objeto de chamada no lado do servidor, o servidor sempre processará a chamada de forma assíncrona. Esse comportamento não será aparente para o cliente, pois o cliente receberá os mesmos parâmetros de saída e o mesmo valor retornado que teria recebido do método síncrono.

Em ambos os casos, a interação entre o cliente e o servidor é marshaled como se a chamada fosse síncrona: a saída de proxies síncronos e assíncronos é indistinguível, assim como a saída dos stubs correspondentes. Esse comportamento simplifica muito o modelo de programação tanto de clientes quanto de servidores. Se um objeto de servidor implementar o ICallFactory, um cliente marshaled não precisará tentar criar um objeto de chamada que possa não estar disponível – para o cliente, um objeto de chamada estará sempre disponível.

Quando o cliente e o servidor estiverem no mesmo apartamento, o objeto do servidor processará qualquer chamada que o cliente fizer. Se um objeto de chamada não estiver disponível, o cliente deverá obter explicitamente a interface síncrona e fazer uma chamada síncrona.

Para obter mais informações, consulte estes tópicos: