非同期クエリの呼び出し
非同期クエリは、書き込みはやや複雑ですが、大きなデータ グループに対してクエリを実行するとシステムまたはネットワークのパフォーマンスが影響を受ける場合に推奨されるクエリの種類です。 スクリプトでは、シンクが受信できるイベントを処理する SWbemSink オブジェクトとサブルーチンを作成することは、基本的なクエリ以外の追加タスクです。
注意
シンクへのコールバックはクライアントが必要とするのと同じ認証レベルでは返されない可能性があるため、非同期ではなく半同期通信を使用することをお勧めします。 詳細については、メソッドの呼び出しに関するページを参照してください。
ローカル マシン上のすべてのデータ ファイルに対して、次の省略形のスクリプト クエリを実行します。 このクエリは、ネットワーク上のすべてのマシンに対して実行された場合には、膨大な時間がかかる可能性があります。 SWbemSink オブジェクトが設定され、処理されるイベントは 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
スクリプトでの非同期メソッド呼び出しの構築に関する詳細については、メソッドの呼び出しに関する記事を参照してください。
C++ アプリケーションでは、クエリ データを受信する別のプロセスが非同期クエリによって生成されます。 マルチスレッド アプリケーションをコーディングする必要がある場合、非同期クエリは同期クエリよりもさらに複雑です。 ただし、非同期クエリによってアプリケーションのメイン スレッドが独占されることはありません。
次の手順では、C++ で非同期クエリを実行する方法について説明します。
C++ で非同期クエリを実行するには
IWbemSink オブジェクトを実装します。
IWbemSink オブジェクトは、非同期操作に関する情報を受け取ります。
IWbemServices::ExecQueryAsync への呼び出しでクエリを記述します。
WMI によって、CIM を照会するプロセスが直ちに別のスレッドに移動し、別のタスクに対してクエリを実行したスレッドが解放されます。
WMI によって IWbemObjectSink::Indicate メソッドが呼び出されるのを待ちます。
完了すると、WMI によって、Indicate が呼び出され、アプリケーションにクエリの完了が通知されます。 また、WMI は、IEnumWbemClassObject インターフェイス ポインターへのポインターとして、シンクにクエリの結果も返します。 同期クエリと同様に、ポインターを使用して、クエリの結果を構成するオブジェクトにアクセスします。
次のコード例は、QuerySink クラスが定義されていないため、エラーを発生させずにコンパイルすることができません。 QuerySink クラスの定義については、IWbemObjectSink に関する記事を参照してください。 また、このコード例では、次の参照と #include ステートメントも必要です。
#include <iostream>
using namespace std;
#include <wbemidl.h>
次のコード例は、非同期呼び出しを行ってクエリを発行する方法を示しています。
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");
}
詳細については、メソッドの呼び出しに関するページを参照してください。