Appel d’une requête asynchrone
Une requête asynchrone, bien qu’elle soit un peu plus complexe à écrire, est le type de requête recommandé quand l’interrogation d’un grand groupe de données impacte les performances du système ou du réseau. Dans le script, la création d’un objet SWbemSink et la création de sous-routines pour gérer les événements que le récepteur peut recevoir sont les seules tâches à faire en plus de la requête de base.
Notes
Étant donné que le rappel au récepteur peut ne pas être retourné au même niveau d’authentification que celui requis par le client, il est recommandé d’utiliser une communication semi-synchrone plutôt qu’une communication asynchrone. Pour plus d’informations, consultez Appel d’une méthode.
L’extrait de script suivant recherche tous les fichiers de données sur la machine locale. Cette requête pourrait prendre énormément de temps si elle était exécutée sur toutes les machines d’un réseau. Un objet SWbemSink est configuré et le seul événement géré est l’événement OnCompleted.
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
Pour plus d’informations sur la construction d’appels de méthodes asynchrones dans un script, consultez Appel d’une méthode.
Dans les applications C++, une requête asynchrone génère un processus distinct pour recevoir des données de requête. Une requête asynchrone est plus complexe qu’une requête synchrone, car vous devez coder une application multithread. En revanche, l’avantage d’une requête asynchrone est qu’elle ne monopolise pas le thread principal de votre application.
La procédure suivante décrit comment effectuer une requête asynchrone en C++.
Pour effectuer une requête asynchrone en C++
Implémentez un objet IWbemSink.
Un objet IWbemSink reçoit certaines informations relatives une opération asynchrone.
Décrivez votre requête dans un appel à IWbemServices::ExecQueryAsync.
WMI déplace immédiatement le processus qui interroge le CIM vers un autre thread, puis libère le thread ayant exécuté la requête pour les besoins d’une autre tâche.
Attendez que WMI appelle la méthode IWbemObjectSink::Indicate.
Quand il a fini, WMI appelle Indicate pour signaler à votre application que la requête est terminée. WMI retourne également les résultats de la requête au récepteur sous forme de pointeur vers un pointeur de l’interface IEnumWbemClassObject. Comme avec une requête synchrone, utilisez le pointeur pour accéder aux objets qui composent le résultat de votre requête.
L’exemple de code suivant ne se compile pas sans erreur, car la classe QuerySink n’a pas été définie. Pour plus d’informations sur la définition de la classe QuerySink, consultez IWbemObjectSink. L’exemple de code nécessite aussi les instructions de référence et #include suivantes.
#include <iostream>
using namespace std;
#include <wbemidl.h>
L’exemple de code suivant montre comment effectuer un appel asynchrone pour émettre une requête.
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");
}
Pour plus d’informations, consultez Appel d’une méthode.