Fazendo e processando chamadas assíncronas
Os objetos COM podem oferecer suporte a chamadas assíncronas. Quando um cliente faz uma chamada assíncrona, o controle retorna ao cliente imediatamente. Enquanto o servidor processa a chamada, o cliente fica 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 naquele 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 de servidor. A interface assíncrona no objeto de chamada tem um nome do formato AsyncInterfaceName. Por exemplo, se um objeto de servidor implementa 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.
Os objetos de servidor que oferecem 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 oferece 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_.
Quando você implementa um objeto de servidor, não é necessário fornecer um objeto de chamada para cada interface que o objeto implementa. Se o objeto de servidor implementa a interface ICallFactory e usa empacotamento padrão, um cliente empacotado sempre pode obter um objeto de chamada de proxy, mesmo se não houver nenhum objeto de chamada no lado do servidor. Esse proxy organizará o 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 empacotada 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, porque o cliente receberá os mesmos parâmetros de saída e o mesmo valor de retorno que teria recebido do método síncrono.
Em ambos os casos, a interação entre cliente e servidor é empacotada 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 de clientes e servidores. Se um objeto de servidor implementa ICallFactory, um cliente empacotado não precisa tentar criar um objeto de chamada que pode não estar disponível — para o cliente, um objeto de chamada está 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 Mais informações, consulte os seguintes tópicos:
- Fazendo uma chamada assíncrona
- Cancelando uma chamada assíncrona
- Cancelando chamadas de método
- Sincronização de chamadas