Realización de una llamada asincrónica
El procedimiento para realizar una llamada sincrónica es sencillo: el cliente obtiene un puntero de interfaz en el objeto de servidor y llama a métodos a través de ese puntero. La llamada asincrónica implica un objeto de llamada, por lo que implica algunos pasos más.
Para cada método de una interfaz sincrónica, la interfaz asincrónica correspondiente implementa dos métodos. Estos métodos asocian los prefijos Begin_ y Finish_ al nombre del método sincrónico. Por ejemplo, si una interfaz denominada ISimpleStream tiene un método Read, la interfaz AsyncISimpleStream tendrá un Begin_Read y un método Finish_Read. Para iniciar una llamada asincrónica, el cliente llama al método Begin_.
Para iniciar una llamada asincrónica
Consulte el objeto de servidor para la interfaz ICallFactory . Si QueryInterface devuelve E_NOINTERFACE, el objeto de servidor no admite llamadas asincrónicas.
Llame a ICallFactory::CreateCall para crear un objeto de llamada correspondiente a la interfaz que desee y, a continuación, suelte el puntero a ICallFactory.
Si no solicitó un puntero a la interfaz asincrónica desde la llamada a CreateCall, consulte el objeto de llamada para la interfaz asincrónica.
Llame al método Begin_ adecuado.
El objeto de servidor ahora está procesando la llamada asincrónica y el cliente puede realizar otro trabajo hasta que necesite los resultados de la llamada.
Un objeto de llamada solo puede procesar una llamada asincrónica a la vez. Si el mismo o un segundo cliente llama a un método Begin_ antes de que finalice una llamada asincrónica pendiente, el método Begin_ devolverá RPC_E_CALL_PENDING.
Si el cliente no necesita los resultados del método Begin_, puede liberar el objeto de llamada al final de este procedimiento. COM detecta esta condición y limpia la llamada. No se llama al método Finish_ y el cliente no obtiene ningún parámetro out ni un valor devuelto.
Cuando el objeto de servidor está listo para devolver desde el método Begin_, indica al objeto de llamada que se realiza. Cuando el cliente está listo, comprueba si se ha señalado el objeto de llamada. Si es así, el cliente puede completar la llamada asincrónica.
El mecanismo para esta señalización y comprobación entre el cliente y el servidor es la interfaz ISynchronize en el objeto de llamada. Normalmente, el objeto de llamada implementa esta interfaz mediante la agregación de un objeto de sincronización proporcionado por el sistema. El objeto de sincronización encapsula un identificador de eventos, que el servidor señala justo antes de volver del método Begin_ mediante una llamada a ISynchronize::Signal.
Para completar una llamada asincrónica
Consulte el objeto de llamada para la interfaz ISynchronize .
Llame a ISynchronize::Wait.
Si Wait devuelve RPC_E_TIMEOUT, el método Begin_ no finaliza el procesamiento. El cliente puede continuar con otro trabajo y llamar a Wait de nuevo más tarde. No puede llamar al método Finish_ hasta que Wait devuelva S_OK.
Si Wait devuelve S_OK, se ha devuelto el método Begin_. Llame al método Finish_ adecuado.
El método Finish_ pasa al cliente los parámetros out. El comportamiento de los métodos asincrónicos, incluido el valor devuelto del método Finish_, debe coincidir exactamente con el del método sincrónico correspondiente.
El cliente puede liberar el objeto de llamada en cuanto se devuelve el método Finish_, o bien puede contener un puntero al objeto de llamada para realizar llamadas adicionales. En cualquier caso, el cliente es responsable de liberar el objeto de llamada cuando el objeto ya no es necesario.
Si llama a un método Finish_ cuando no hay ninguna llamada en curso, el método devolverá RPC_E_CALL_COMPLETE.
Nota
Si los objetos de cliente y servidor están en el mismo apartamento, no se garantiza que las llamadas a ICallFactory::CreateCall se realicen correctamente. Si el objeto de servidor no admite llamadas asincrónicas en una interfaz determinada, se producirá un error en el intento de crear un objeto de llamada y el cliente debe usar la interfaz sincrónica.
Temas relacionados