Share via


Esecuzione di una chiamata asincrona con C++

Le applicazioni WMI scritte in C++ possono effettuare chiamate asincrone usando molti dei metodi dell'interfaccia COM IWbemServices . Tuttavia, la procedura consigliata per chiamare un metodo WMI o un metodo provider consiste nell'usare chiamate semisynchronous perché le chiamate semisynchronous sono più sicure delle chiamate asincrone. Per altre informazioni, vedere Esecuzione di una chiamata semisynchrono con C++ e impostazione della sicurezza in una chiamata asincrona.

La procedura seguente descrive come effettuare una chiamata asincrona usando il sink nel processo.

Per effettuare una chiamata asincrona con C++

  1. Implementare l'interfaccia IWbemObjectSink .

    Tutte le applicazioni che effettuano chiamate asincrone devono implementare IWbemObjectSink. I consumer di eventi temporanei implementano anche IWbemObjectSink per ricevere la notifica degli eventi.

  2. Accedere allo spazio dei nomi WMI di destinazione.

    Le applicazioni devono sempre chiamare la funzione COM CoInitializeSecurity durante la fase di inizializzazione. Se non lo fanno prima di effettuare una chiamata asincrona, WMI rilascia il sink dell'applicazione senza completare la chiamata asincrona. Per altre informazioni, vedere Inizializzazione di COM per un'applicazione WMI.

  3. Impostare la sicurezza per il sink.

    Le chiamate asincrone creano un'ampia gamma di problemi di sicurezza che potrebbe essere necessario gestire, ad esempio, consentendo l'accesso WMI all'applicazione. Per altre informazioni, vedere Impostazione della sicurezza in una chiamata asincrona.

  4. Effettuare la chiamata asincrona.

    Il metodo restituisce immediatamente con il codice WBEM_S_NO_ERROR operazione riuscita. L'applicazione può procedere con altre attività durante l'attesa del completamento dell'operazione. WMI riporta all'applicazione chiamando i metodi nell'implementazione IWbemObjectSink dell'applicazione.

  5. Se necessario, controllare periodicamente l'implementazione per gli aggiornamenti.

    Le applicazioni possono ricevere una notifica dello stato intermedio impostando il parametro lFlags nella chiamata asincrona a WBEM_FLAG_SEND_STATUS. WMI segnala lo stato della chiamata impostando il parametro lFlags di IWbemObjectSink su WBEM_STATUS_PROGRESS.

  6. Se necessario, è possibile annullare la chiamata prima che WMI finisca l'elaborazione chiamando il metodo IWbemServices::CancelCallAsync .

    Il metodo CancelAsyncCall annulla l'elaborazione asincrona rilasciando immediatamente il puntatore all'interfaccia IWbemObjectSink e garantisce che il puntatore venga rilasciato prima che CancelAsyncCall restituisca .

    Se si usa un oggetto wrapper che implementa l'interfaccia IUnsecured per ospitare IWbemObjectSink, potrebbero verificarsi alcune complicazioni aggiuntive. Poiché l'applicazione deve passare lo stesso puntatore a CancelAsyncCall passato nella chiamata asincrona originale, l'applicazione deve mantenere l'oggetto wrapper finché non diventa chiaro che l'annullamento non è necessario. Per altre informazioni, vedere Impostazione della sicurezza in una chiamata asincrona.

  7. Al termine, pulire i puntatori e arrestare l'applicazione.

    WMI fornisce la chiamata di stato finale tramite il metodo SetStatus .

    Nota

    Dopo aver inviato l'aggiornamento dello stato finale, WMI rilascia il sink dell'oggetto chiamando il metodo Release per la classe che implementa l'interfaccia IWbemObjectSink . Nell'esempio precedente si tratta del metodo QuerySink::Release . Se si vuole avere il controllo sulla durata dell'oggetto sink, è possibile implementare il sink con un conteggio dei riferimenti iniziale di uno (1).

     

    Se un'applicazione client passa la stessa interfaccia sink in due diverse chiamate asincrone sovrapposte, WMI non garantisce l'ordine del callback. Un'applicazione client che effettua chiamate asincrone sovrapposte deve passare oggetti sink diversi o serializzare le chiamate.

L'esempio seguente richiede il riferimento e le istruzioni #include seguenti.

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

Nell'esempio seguente viene descritto come eseguire una query asincrona usando il metodo ExecQueryAsync , ma non crea impostazioni di sicurezza o rilascia l'oggetto IWbemObjectSink . Per altre informazioni, vedere Impostazione della sicurezza in una chiamata asincrona.

// 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

Il codice precedente non viene compilato senza errori perché la classe QuerySink non è stata definita. Per altre informazioni su QuerySink, vedere IWbemObjectSink.

 

Chiamata di un metodo