Fazendo uma chamada assíncrona
O procedimento para fazer uma chamada síncrona é simples: o cliente obtém um ponteiro de interface no objeto do servidor e chama métodos por meio desse ponteiro. A chamada assíncrona envolve um objeto de chamada, portanto, envolve mais algumas etapas.
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_.
Para iniciar uma chamada assíncrona
Consulte o objeto do servidor para a interface ICallFactory . Se QueryInterface retornar E_NOINTERFACE, o objeto de servidor não oferece suporte a chamadas assíncronas.
Chame ICallFactory::CreateCall para criar um objeto de chamada correspondente à interface desejada e solte o ponteiro para ICallFactory.
Se você não solicitou um ponteiro para a interface assíncrona da chamada para CreateCall, consulte o objeto de chamada para a interface assíncrona.
Chame o método Begin_ apropriado.
O objeto de servidor agora está processando a chamada assíncrona e o cliente está livre para fazer outro trabalho até que precise dos resultados da chamada.
Um objeto de chamada pode processar apenas uma chamada assíncrona por vez. Se o mesmo ou um segundo cliente chamar um método Begin_ antes que uma chamada assíncrona pendente seja concluída, o método Begin_ retornará RPC_E_CALL_PENDING.
Se o cliente não precisar dos resultados do método Begin_, ele poderá liberar o objeto de chamada no final deste procedimento. COM detecta essa condição e limpa a chamada. O método Finish_ não é chamado e o cliente não obtém nenhum parâmetro de saída ou um valor de retorno.
Quando o objeto de servidor está pronto para retornar do método Begin_, ele sinaliza ao objeto de chamada que ele foi feito. Quando o cliente estiver pronto, ele verificará se o objeto de chamada foi sinalizado. Em caso afirmativo, o cliente pode concluir a chamada assíncrona.
O mecanismo para essa sinalização e verificação entre cliente e servidor é a interface ISynchronize no objeto de chamada. O objeto de chamada normalmente implementa essa interface agregando um objeto de sincronização fornecido pelo sistema. O objeto de sincronização encapsula um identificador de evento, que o servidor sinaliza pouco antes de retornar do método Begin_ chamando ISynchronize::Signal.
Para concluir uma chamada assíncrona
Consulte o objeto de chamada para a interface ISynchronize.
Chame ISynchronize::Aguarde.
Se Wait retornar RPC_E_TIMEOUT, o Begin_ método não concluiu o processamento. O cliente pode continuar com outro trabalho e chamar Esperar novamente mais tarde. Ele não pode chamar o método Finish_ até que Wait retorne S_OK.
Se Wait retornar S_OK, o método Begin_ retornou. Chame o método Finish_ apropriado.
O método Finish_ passa o cliente para fora parâmetros. O comportamento dos métodos assíncronos, incluindo o valor de retorno do método Finish_, deve corresponder exatamente ao do método síncrono correspondente.
O cliente pode liberar o objeto de chamada assim que o método Finish_ retorna, ou pode manter um ponteiro para o objeto de chamada para fazer chamadas adicionais. Em ambos os casos, o cliente é responsável por liberar o objeto de chamada quando o objeto não for mais necessário.
Se você chamar um método Finish_ quando nenhuma chamada estiver em andamento, o método retornará RPC_E_CALL_COMPLETE.
Observação
Se os objetos cliente e servidor estiverem no mesmo apartamento, as chamadas para ICallFactory::CreateCall não terão garantia de êxito. Se o objeto de servidor não oferecer suporte a chamada assíncrona em uma interface específica, a tentativa de criar um objeto de chamada falhará e o cliente deverá usar a interface síncrona.
Tópicos relacionados