Aufrufen einer asynchronen Abfrage
Eine asynchrone Abfrage ist zwar etwas komplexer zu schreiben, ist aber der bevorzugte Abfragetyp, wenn die System- oder Netzwerkleistung durch Abfragen einer großen Datengruppe beeinträchtigt wird. Im Skript ist das Erstellen eines SWbemSink-Objekts und von Unterroutinen zum Behandeln der Ereignisse, die die Senke empfangen kann, die einzige zusätzliche Aufgabe, die über die grundlegende Abfrage hinausgehen.
Hinweis
Da der Rückruf an die Senke möglicherweise nicht auf der Authentifizierungsebene zurückgegeben wird, die der Client benötigt, empfiehlt es sich, anstelle der asynchronen Kommunikation eine halbsynchrone Kommunikation zu verwenden. Weitere Informationen finden Sie unter Aufrufen einer Methode.
Die folgenden abgekürzten Skripts fragen alle Datendateien auf dem lokalen Computer ab. Diese Abfrage kann sehr viel Zeit in Anspruch nehmen, wenn sie für alle Computer in einem Netzwerk ausgeführt wird. Ein SWbemSink-Objekt wird eingerichtet, und das einzige Ereignis, das behandelt wird, ist das OnCompleted-Ereignis.
Sub SINK_OnCompleted(iHResult, objErrorObject, objAsyncContext)
WScript.Echo "Asynchronous operation is done."
End Sub
Set service = GetObject("winmgmts:")
Set sink = WScript.CreateObject("WbemScripting.SWbemSink","SINK_")
service.ExecQueryAsync sink, "SELECT * FROM Win32_DataFile"
WScript.Echo "Waiting for instances."
sink.Cancel()
set sink= Nothing
Ausführliche Informationen zum Erstellen asynchroner Methodenaufrufe im Skript finden Sie unter Aufrufen einer Methode.
In C++-Anwendungen erzeugt eine asynchrone Abfrage einen separaten Prozess zum Empfangen von Abfragedaten. Eine asynchrone Abfrage ist komplexer als eine synchrone Abfrage, da Sie eine Multithreadanwendung programmieren müssen. Bei einer asynchronen Abfrage wird der Hauptthread Ihrer Anwendung jedoch nicht monopolisiert.
Im folgenden Verfahren wird beschrieben, wie eine asynchrone Abfrage in C++ ausgeführt wird.
So führen Sie eine asynchrone Abfrage in C++ aus
Implementieren Sie ein IWbemSink-Objekt.
Ein IWbemSink-Objekt empfängt Informationen zu einem asynchronen Vorgang.
Beschreiben Sie Ihre Abfrage in einem Aufruf von IWbemServices::ExecQueryAsync.
WMI verschiebt den Prozess, der CIM abfragt, sofort in einen anderen Thread und gibt den Thread frei, der die Abfrage für eine andere Aufgabe ausgeführt hat.
Warten Sie, bis WMI die Methode IWbemObjectSink::Indicate aufruft.
Nach Abschluss ruft WMI Indicate auf, um Ihrer Anwendung zu signalisieren, dass die Abfrage abgeschlossen ist. WMI gibt außerdem Ergebnisse der Abfrage an die Senke als Zeiger auf einen IEnumWbemClassObject-Schnittstellenzeiger zurück. Verwenden Sie wie bei einer synchronen Abfrage den Zeiger, um auf die Objekte zuzugreifen, aus denen das Ergebnis ihrer Abfrage besteht.
Im folgenden Codebeispiel ist die Kompilierung nicht fehlerfrei, da die Klasse „QuerySink“ nicht definiert wurde. Informationen zum Definieren der QuerySink-Klasse finden Sie unter IWbemObjectSink. Im folgenden Codebeispiel sind außerdem die folgenden Verweise und #include-Anweisungen erforderlich:
#include <iostream>
using namespace std;
#include <wbemidl.h>
Im folgenden Codebeispiel wird gezeigt, wie Sie einen asynchronen Aufruf zum Ausstellen einer Abfrage ausführen.
void ExecQuery(IWbemServices *pSvc)
{
// Create a new sink object.
QuerySink *pSink = new QuerySink;
// Initialize the query and query language.
BSTR strQuery = SysAllocString(L"SELECT * FROM ClassName");
BSTR strQueryLang = SysAllocString(L"WQL");
// Issue the query.
HRESULT hRes = pSvc->ExecQueryAsync(strQueryLang, strQuery, 0,
NULL, pSink);
// Clean up.
SysFreeString(strQuery);
SysFreeString(strQueryLang);
if (hRes)
{
printf("ExecQueryAsync failed with = 0x%X\n", hRes);
return;
}
printf("Completed.\n");
}
Weitere Informationen finden Sie unter Aufrufen einer Methode.