У меня есть поток, который создает COM-объекты, для которых требуется однопоточная квартира.
Изначально основная функция этого потока помещала его в цикл WaitForMultipleObjects.Очевидно, это проблема, потому что она не позволяет насосу сообщений COM выполнять свою работу.
Я заменил это на MsgWaitForMultipleObjects в качестве решения, но теперь я сталкиваюсь с проблемой: иногда MsgWaitForMultipleObjects (часто) возвращает WAIT_FAILED, но не устанавливает ошибку.
Код обрабатывает возвращаемое значение WAIT_FAILED, просто продолжая и пытаясь вызвать MsgWaitForMultipleObjects снова.Вызов MsgWaitForMultipleObjects может возвращать WAIT_FAILED несколько раз (максимум, что я видел, это 9), но затем он неожиданно работает без проблем.
Код написан так, чтобы он мог потенциально зайти в бесконечный цикл, если бы функция возвращала WAIT_FAILED по уважительной причине.Я знаю, что должен это исправить, но в настоящий момент я считаю, что это «обходной путь», потому что вызов MsgWaitForMultipleObjects в конечном итоге завершится успешно.
Этот код тестируется в Windows 7, Vista и XP (все32-битная, Windows 7 32-битная и 64-битная).
Кто-нибудь знает, почему это происходит?
Соответствующий код:
bool run = true;
while (run)
{
DWORD ret = MsgWaitForMultipleObjects(2, events, FALSE, INFINITE,
QS_ALLINPUT);
switch (ret)
{
case WAIT_OBJECT_0:
{
ResetEvent(events[0]);
ProcessWorkQueue();
break;
}
case WAIT_OBJECT_0 + 1:
{
run = false;
break;
}
case WAIT_OBJECT_0 + 2:
{
MSG msg;
while (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
DispatchMessage(&msg);
break;
}
case WAIT_FAILED:
{
Logger::Output(L"Wait failed in Notify::Run(), error is "
+ boost::lexical_cast<std::wstring>(GetLastError()));
}
}
}
Примервывод будет:
Wait failed in Notify::Run(), error is 0
Wait failed in Notify::Run(), error is 0
Wait failed in Notify::Run(), error is 0
Wait failed in Notify::Run(), error is 0
Wait failed in Notify::Run(), error is 0
Wait failed in Notify::Run(), error is 0
Wait failed in Notify::Run(), error is 0
Wait failed in Notify::Run(), error is 0
Wait failed in Notify::Run(), error is 0
// At this point, the wait succeeds
Я считаю, что возвращаемое значение WAIT_FAILED происходит только после того, как ожидание было прервано сообщением.