Создание полусинхронного вызова с помощью C++
Полусинхронные вызовы являются рекомендуемыми средствами для вызова методов WMI, таких как IWbemServices::ExecMethod и методы поставщика, такие как Win32_LogicalDisk метод Chkdsk класса.
Одним из недостатков синхронной обработки является блокировка потока вызывающего объекта до завершения вызова. Блокировка может привести к задержке во время обработки. В отличие от этого, асинхронный вызов должен реализовывать SWbemSink в скрипте. В C++ асинхронный код должен реализовать интерфейс IWbemObjectSink, использовать несколько потоков и управлять передачей информации назад вызывающей стороне. Большие результирующие наборы из запросов, например, могут занимать значительное время для передачи и заставляют запрашивающую сторону тратить значительные системные ресурсы для обработки передачи.
Полусинхронная обработка решает проблемы блокировки потока и неконтролируемой доставки путем опроса специального объекта состояния, реализующего интерфейс IWbemCallResult. С помощью IWbemCallResultможно повысить скорость и эффективность запросов, перечислений и уведомлений о событиях.
В следующей процедуре описывается, как выполнить полусинхронный вызов с помощью интерфейса IWbemServices.
Для выполнения полусинхронного вызова с интерфейсом IWbemServices
Выполните вызов как обычно, но с флагом WBEM_FLAG_RETURN_IMMEDIATELY в параметре IFlags.
Вы можете объединить WBEM_FLAG_RETURN_IMMEDIATELY с другими флагами, допустимыми для конкретного метода. Например, используйте флаг WBEM_FLAG_FORWARD_ONLY для всех вызовов, возвращающих перечислители. Настройка этих флагов в сочетании экономит время и пространство, а также повышает скорость реагирования.
Опрос результатов.
При вызове метода, возвращающего перечислитель, например, IWbemServices::CreateClassEnum или IWbemServices::ExecQuery, можно опрашивать перечислители с помощью методов IEnumWbemClassObject::Next или IEnumWbemClassObject::NextAsync. Вызов IEnumWbemClassObject::NextAsync неблокируется и возвращается немедленно. В фоновом режиме WMI начинает доставлять запрошенный номер объектов, вызывая IWbemObjectSink::Укажите. Затем WMI останавливается и ожидает другого вызова NextAsync.
При вызове метода, который не возвращает перечислитель, например IWbemServices::GetObject, необходимо задать для параметра ppCallResult допустимый указатель. Используйте IWbemCallResult::GetCallStatus, чтобы получить WBEM_S_NO_ERROR.
Завершите звонок.
Для вызова, возвращающего перечислитель, WMI вызывает IWbemObjectSink::SetStatus, чтобы сообщить о завершении операции. Если вам не нужен весь результат, освободите перечислитель, вызвав метод IEnumWbemClassObject::Release. Вызов выпуска приводит к тому, что WMI отменяет доставку всех оставшихся объектов.
Для вызова, который не использует перечислитель, получите объект GetCallStatus через параметр plStatus в вашем методе.
Пример кода 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.
}
Связанные разделы