半異步呼叫是呼叫 WMI 方法的建議方法,例如 IWbemServices::ExecMethod 和提供者方法,例如 Win32_LogicalDisk 類別的Chkdsk 方法。
同步處理的其中一個缺點是呼叫端線程會遭到封鎖,直到呼叫完成為止。 封鎖可能會導致處理時間延遲。 相反地,異步呼叫必須在腳本中實作 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.
}
相關主題