Realización de una llamada asincrónica con C++

Las aplicaciones WMI escritas en C++ pueden realizar llamadas asincrónicas mediante muchos de los métodos de la interfaz COM de IWbemServices. Sin embargo, el procedimiento recomendado para llamar a un método de WMI o un método de proveedor es mediante llamadas semisincrónicas, porque las llamadas semisincrónicas son más seguras que las llamadas asincrónicas. Para obtener más información, consulte Realizar una llamada semisincrónica con C++ y Establecer la seguridad en una llamada asincrónica.

En el procedimiento siguiente se describe cómo realizar una llamada asincrónica mediante el receptor del proceso.

Para realizar una llamada asincrónica mediante C++

  1. Implemente la interfaz IWbemObjectSink.

    Todas las aplicaciones que realizan llamadas asincrónicas deben implementar IWbemObjectSink. Los consumidores de eventos temporales también implementan IWbemObjectSink para recibir notificaciones de eventos.

  2. Inicie sesión en el espacio de nombres de WMI de destino.

    Las aplicaciones siempre tienen que llamar a la función COM CoInitializeSecurity durante la fase de inicialización. Si no lo hacen antes de realizar una llamada asincrónica, WMI libera el receptor de la aplicación sin completar la llamada asincrónica. Para obtener más información, consulte Inicialización de COM para una aplicación WMI.

  3. Establezca la seguridad del receptor.

    Las llamadas asincrónicas crean una variedad de problemas de seguridad con los que puede tener que lidiar, por ejemplo, permitir el acceso de WMI a la aplicación. Para obtener más información, consulte Establecer la seguridad en una llamada asincrónica.

  4. Realice la llamada asincrónica.

    El método devuelve inmediatamente el código de operación correcta WBEM_S_NO_ERROR. La aplicación puede continuar con otras tareas mientras espera a que se complete la operación. WMI informa de nuevo a la aplicación llamando a métodos en la implementación IWbemObjectSink de la aplicación.

  5. Si es necesario, compruebe la implementación periódicamente para ver las posibles actualizaciones.

    Las aplicaciones pueden recibir notificaciones de estado intermedio estableciendo el parámetro lFlags en la llamada asincrónica a WBEM_FLAG_SEND_STATUS. WMI notifica el estado de la llamada estableciendo el parámetro lFlags de IWbemObjectSink en WBEM_STATUS_PROGRESS.

  6. Si es necesario, puede cancelar la llamada antes de que WMI finalice el procesamiento llamando al método IWbemServices::CancelCallAsync.

    El método CancelAsyncCall cancela el procesamiento asincrónico liberando inmediatamente el puntero a la interfaz IWbemObjectSink y garantiza que el puntero se libere antes de que se devuelva CancelAsyncCall.

    Si usa un objeto contenedor que implementa la interfaz IUnsecured para hospedar IWbemObjectSink, puede encontrarse con algunas complicaciones adicionales. Dado que la aplicación debe pasar el mismo puntero a CancelAsyncCall que se pasó en la llamada asincrónica original, la aplicación debe mantenerse en el objeto contenedor hasta que quede claro que la cancelación no es necesaria. Para obtener más información, consulte Establecer la seguridad en una llamada asincrónica.

  7. Cuando termine, limpie los punteros y apague la aplicación.

    WMI proporciona la llamada de estado final a través del método SetStatus.

    Nota

    Después de enviar la actualización de estado final, WMI libera el receptor de objetos llamando al método Release para la clase que implementa la interfaz IWbemObjectSink. En el ejemplo anterior, este es el método QuerySink::Release. Si quiere tener control sobre la duración del objeto receptor, puede implementar el receptor con un recuento de referencias inicial de uno (1).

     

    Si una aplicación cliente pasa la misma interfaz de receptor en dos llamadas asincrónicas superpuestas diferentes, WMI no garantiza el orden de la devolución de llamada. Una aplicación cliente que realiza llamadas asincrónicas superpuestas debe pasar objetos receptores diferentes o serializar las llamadas.

En el ejemplo siguiente se requiere la siguiente referencia e instrucciones #include.

#include <iostream>
using namespace std;
#pragma comment(lib, "wbemuuid.lib")
#include <wbemidl.h>

En el ejemplo siguiente se describe cómo realizar una consulta asincrónica mediante el método ExecQueryAsync, pero no se crean configuraciones de seguridad ni se libera el objeto IWbemObjectSink. Para obtener más información, consulte Establecer la seguridad en una llamada asincrónica.

// Set input parameters to ExecQueryAsync.
BSTR QueryLang = SysAllocString(L"WQL");
BSTR Query = SysAllocString(L"SELECT * FROM MyClass");

// Create IWbemObjectSink object and set pointer.
QuerySink *pSink = new QuerySink;

IWbemServices* pSvc = 0;

// Call ExecQueryAsync.
HRESULT hRes = pSvc->ExecQueryAsync(QueryLang, 
                                    Query, 
                                    0, 
                                    NULL, 
                                    pSink);

// Check for errors.
if (hRes)
{
    printf("ExecQueryAsync failed with = 0x%X\n", hRes);
    SysFreeString(QueryLang);
    SysFreeString(Query);
    delete pSink;    
    return ERROR;
}

Nota

El código anterior no se compila sin error porque no se ha definido la clase QuerySink. Para obtener más información sobre QuerySink, consulte IWbemObjectSink.

 

Llamada a un método