Недавно столкнулся с интересным случаем, когда при завершении работы системы отображалось окно "Программа завершается... Пожалуйста подождите" со временем переходящее в "Программа не отвечает". Ситуация воспроизводилась не каждый раз, но более-менее стабильно.
Т.о. цикл историй о "зависаниях" при завершении работы системы продолжается :).
Используя методику, описанную в [1], было снято два дампа и найден "провинившийся" поток. Им оказался один из рабочих потоков, который находился в режиме ожидания (WaitForMultipleObjects). Т.е. работу свою он сделал и спал, ожидая, когда вновь понадобятся его услуги.
Возник вопрос - как так получилось, что система именно ему шлет сообщение WM_QUERYENDSESSION (тут дело ясное, что до WM_ENDSESSION дело не доходит)? С помощью spy++ выяснилось, что у этого потока есть окно класса "MsoStdCompMgr" без заголовка. Такое окно могло быть создано только какой-то сторонней библиотекой.
Расследование продолжилось. В ходе его удалось выяснить, что окно это создает Microsoft Office component (вызов CreateWindow был сделан из недр mso.dll). В этот момент рабочий поток выполнял задачу по вычитыванию адресной книги средствами MAPI.
И вот что оказалось: после финализации MAPI это окно не уничтожалось (DestroyWindow для него не вызывался), рабочий поток засыпал, цикл выборки сообщений он не крутил. А система, видя, что у этого потока есть окно, посылала ему сообщение WM_QUERYENDSESSION при завершении работы системы. А поток это дело "игнорировал" по причине отсутствия цикла выборки сообщений :). Вот такие пироги.
Такая ситуация возникает при работе с Exchange address book provider через MAPI, если установлен Outlook 2003/2007 (правда не факт, что с последними заплатками). В качестве Workaround-а можно использовать завершение рабочего потока, после вычитывание адресной книги.
Ссылки
[1] Методика диагностики зависания приложения при shutdown-е
Подписаться на:
Комментарии к сообщению (Atom)
Комментариев нет:
Отправить комментарий