다음을 통해 공유


C++를 사용하여 반동기 호출 만들기

반동기 호출은 Win32_LogicalDisk 클래스Chkdsk 메서드와 같은 IWbemServices::ExecMethod 및 공급자 메서드와 같은 WMI 메서드를 호출하는 데 권장되는 방법입니다.

동기 처리의 한 가지 단점은 호출이 완료될 때까지 호출자 스레드가 차단된다는 것입니다. 차단으로 인해 처리 시간이 지연될 수 있습니다. 반면, 비동기 호출은 스크립트에서 SWbemSink구현해야 합니다. C++에서 비동기 코드는 IWbemObjectSink 인터페이스를 구현하고, 여러 스레드를 사용하고, 호출자에게 정보 흐름을 제어해야 합니다. 예를 들어 쿼리의 큰 결과 집합은 배달하는 데 상당한 시간이 걸릴 수 있으며 호출자가 배달을 처리하기 위해 상당한 시스템 리소스를 소비하도록 강제할 수 있습니다.

준동기 처리는 IWbemCallResult 인터페이스를 구현하는 특수 상태 개체를 조회하여 스레드 차단 및 제어되지 않은 배달 문제를 모두 해결합니다. IWbemCallResult통해 쿼리, 열거형 및 이벤트 알림의 속도와 효율성을 향상시킬 수 있습니다.

다음 절차에서는 IWbemServices 인터페이스를 사용하여 반동기 호출을 수행하는 방법을 설명합니다.

IWbemServices 인터페이스를 사용하여 반동기 호출을 수행하려면

  1. 정상적으로 호출하되, IFlags 매개 변수에 WBEM_FLAG_RETURN_IMMEDIATELY 플래그를 설정하여 호출하세요.

    WBEM_FLAG_RETURN_IMMEDIATELY 특정 메서드에 유효한 다른 플래그와 결합할 수 있습니다. 예를 들어 열거자를 반환하는 모든 호출에 WBEM_FLAG_FORWARD_ONLY 플래그를 사용합니다. 이러한 플래그를 조합하여 설정하면 시간과 공간이 절약되고 응답성이 향상됩니다.

  2. 결과를 확인하세요.

    열거자를 반환하는 메서드를 호출하는 경우 IWbemServices::CreateClassEnum 또는 IWbemServices::ExecQuery같은 IEnumWbemClassObject::Next 또는 IEnumWbemClassObject::NextAsync 메서드를 사용하여 열거자를 폴링할 수 있습니다. IEnumWbemClassObject::NextAsync 호출이 차단되지 않고 즉시 반환됩니다. 백그라운드에서 WMI는 IWbemObjectSink::indicate호출하여 요청된 개체 수를 전달하기 시작합니다. WMI는 그런 다음 중지 상태가 되어, NextAsync 호출이 다시 올 때까지 기다립니다.

    IWbemServices::GetObject같은 열거자를 반환하지 않는 메서드를 호출하는 경우 ppCallResult 매개 변수를 유효한 포인터로 설정해야 합니다. 반환된 포인터에서 IWbemCallResult::GetCallStatus 사용하여 WBEM_S_NO_ERROR가져옵니다.

  3. 통화를 마칩니다.

    열거자를 반환하는 호출의 경우 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.            
  
}

메서드 호출