반동기 호출은 Win32_LogicalDisk 클래스Chkdsk 메서드와 같은 IWbemServices::ExecMethod 및 공급자 메서드와 같은 WMI 메서드를 호출하는 데 권장되는 방법입니다.
동기 처리의 한 가지 단점은 호출이 완료될 때까지 호출자 스레드가 차단된다는 것입니다. 차단으로 인해 처리 시간이 지연될 수 있습니다. 반면, 비동기 호출은 스크립트에서 SWbemSink구현해야 합니다. C++에서 비동기 코드는 IWbemObjectSink 인터페이스를 구현하고, 여러 스레드를 사용하고, 호출자에게 정보 흐름을 제어해야 합니다. 예를 들어 쿼리의 큰 결과 집합은 배달하는 데 상당한 시간이 걸릴 수 있으며 호출자가 배달을 처리하기 위해 상당한 시스템 리소스를 소비하도록 강제할 수 있습니다.
준동기 처리는 IWbemCallResult 인터페이스를 구현하는 특수 상태 개체를 조회하여 스레드 차단 및 제어되지 않은 배달 문제를 모두 해결합니다. IWbemCallResult통해 쿼리, 열거형 및 이벤트 알림의 속도와 효율성을 향상시킬 수 있습니다.
다음 절차에서는 IWbemServices 인터페이스를 사용하여 반동기 호출을 수행하는 방법을 설명합니다.
IWbemServices 인터페이스를 사용하여 반동기 호출을 수행하려면
정상적으로 호출하되, IFlags 매개 변수에 WBEM_FLAG_RETURN_IMMEDIATELY 플래그를 설정하여 호출하세요.
WBEM_FLAG_RETURN_IMMEDIATELY 특정 메서드에 유효한 다른 플래그와 결합할 수 있습니다. 예를 들어 열거자를 반환하는 모든 호출에 WBEM_FLAG_FORWARD_ONLY 플래그를 사용합니다. 이러한 플래그를 조합하여 설정하면 시간과 공간이 절약되고 응답성이 향상됩니다.
결과를 확인하세요.
열거자를 반환하는 메서드를 호출하는 경우 IWbemServices::CreateClassEnum 또는 IWbemServices::ExecQuery같은 IEnumWbemClassObject::Next 또는 IEnumWbemClassObject::NextAsync 메서드를 사용하여 열거자를 폴링할 수 있습니다. IEnumWbemClassObject::NextAsync 호출이 차단되지 않고 즉시 반환됩니다. 백그라운드에서 WMI는 IWbemObjectSink::indicate호출하여 요청된 개체 수를 전달하기 시작합니다. WMI는 그런 다음 중지 상태가 되어, NextAsync 호출이 다시 올 때까지 기다립니다.
IWbemServices::GetObject같은 열거자를 반환하지 않는 메서드를 호출하는 경우 ppCallResult 매개 변수를 유효한 포인터로 설정해야 합니다. 반환된 포인터에서 IWbemCallResult::GetCallStatus 사용하여 WBEM_S_NO_ERROR가져옵니다.
통화를 마칩니다.
열거자를 반환하는 호출의 경우 WMI는 IWbemObjectSink::SetStatus 호출하여 작업 완료를 보고합니다. 전체 결과가 필요하지 않은 경우 IEnumWbemClassObject::Release 메서드를 호출하여 열거자를 해제합니다. Release을 호출하면 남아 있는 모든 개체의 배달을 WMI가 취소합니다.
열거자를 사용하지 않는 호출의 경우 메서드의 plStatus 매개 변수를 통해 GetCallStatus 개체를 검색합니다.
이 항목의 C++ 코드 예제에서는 다음 #include 문을 올바르게 컴파일해야 합니다.
#include <comdef.h>
#include <wbemidl.h>
다음 코드 예제에서는 방식으로 GetObject를 세미동기 호출하는 방법을 보여 줍니다.
void GetObjSemiSync(IWbemServices *pSvc)
{
IWbemCallResult *pCallRes = 0;
IWbemClassObject *pObj = 0;
HRESULT hRes = pSvc->GetObject(_bstr_t(L"MyClass=\"AAA\""), 0,
0, 0, &pCallRes
);
if (hRes || pCallRes == 0)
return;
while (true)
{
LONG lStatus = 0;
HRESULT hRes = pCallRes->GetCallStatus(5000, &lStatus);
if ( hRes == WBEM_S_NO_ERROR || hRes != WBEM_S_TIMEDOUT )
break;
// Do another task
}
hRes = pCallRes->GetResultObject(5000, &pObj);
if (hRes)
{
pCallRes->Release();
return;
}
pCallRes->Release();
// Use the object.
// ...
// Release it.
// ===========
pObj->Release(); // Release objects not owned.
}
관련 항목
-
메서드 호출