Проблема с использованием UnhandledException в приложении Windows Mobile

У меня есть программа для Windows Mobile, которая обращается к подключенному устройству через стороннюю DLL. Каждый вызов устройства может занять неизвестное время, поэтому каждый вызов включает свойство тайм-аута. Если для возврата вызова требуется больше времени, чем указанный тайм-аут, DLL вместо этого выдает исключение, которое мое приложение перехватывает без проблем.

У меня проблема с закрытием приложения. Если мое приложение вызвало DLL и ожидает истечения тайм-аута, а затем я закрываю приложение до истечения тайм-аута, мое приложение блокируется и требует перезагрузки КПК.

Я могу гарантировать, что приложение ожидает тайм-аута перед закрытием в нормальных условиях. Однако я пытаюсь использовать AppDomain.CurrentDomain.UnhandledException для перехвата любых необработанных исключений в программе и использовать событие для ожидания истечения этого ожидающего тайм-аута, чтобы программа могла быть окончательно закрыта.

Моя проблема в том, что это мероприятие не продлится достаточно долго. Если я помещаю в событие строку MessageBox.Show("unhandled exception");, а затем выбрасываю новое необработанное исключение из основной формы моего приложения, я вижу окно сообщения на долю секунды, но затем оно исчезает без нажатия кнопки ОК.

Документация, которую я нашел по этому событию, предполагает, что к моменту его вызова приложение полностью готово к закрытию, и закрытие не может быть остановлено, но я не думал, что это означает, что сам метод события не завершится. Что дает (думаю, вот в чем вопрос)?

Обновление: в полноэкранном режиме (Vista) это работает должным образом, но только если я использую событие Application.ThreadException, которого нет в .Net CF 2.0.


person MusiGenesis    schedule 12.04.2010    source источник
comment
Ваш длительный (?) Вызов DLL не может быть отменен в первый раз? Просто чтобы убедиться...   -  person Marcel    schedule 12.04.2010
comment
Я мог бы представить, что в этом случае представление элемента управления, требующего взаимодействия с пользователем, не будет работать должным образом - что, если вместо этого вы напишете какой-нибудь текст в файл журнала? Вы также можете попробовать поместить try-catch в метод UnhandledException, чтобы узнать, генерирует ли сам MessageBox какое-то исключение ApplicationClosingException (я только что придумал это) или что-то в этом роде.   -  person C.Evenhuis    schedule 12.04.2010
comment
@Marcel: длительный вызов не может быть отменен каким-либо образом, насколько я могу понять, поэтому пока я застрял в ожидании его завершения. Рассматриваемое устройство представляет собой считыватель магнитных карт; чтобы использовать его, вы должны вызвать метод чтения в отдельном потоке, а затем подождать, пока карта не будет перемещена, либо будет сгенерировано исключение тайм-аута. Если при закрытии приложения есть выдающееся чтение, мне нужно провести опрос и дождаться истечения времени ожидания, прежде чем разрешить закрытие приложения.   -  person MusiGenesis    schedule 12.04.2010
comment
@deltreme: Я собираюсь попробовать что-то другое, кроме MessageBox, чтобы увидеть, есть ли проблема только с этим вызовом.   -  person MusiGenesis    schedule 12.04.2010


Ответы (1)


Я тоже столкнулся с этой проблемой. Это известная проблема в .NET CF (v2.0), но у меня она также была при использовании v3.5 (хотя ситуации, в которых она возникает, более специфичны). Вы можете найти (старый и все еще активный) отчет об ошибке здесь.

Вызов MessageBox.Show () вызывает его немедленное закрытие, но в моем случае было два обходных пути: 1) Вызов MessageBox.Show () во второй раз. Затем он блокируется, пока не будет закрыт пользователем. Вы можете проверить преждевременное закрытие первого MessageBox.Show (), проверив DialogResult. Я не помню, какой результат он вернул именно тогда, когда он потерпел неудачу, я помню, что он дал результат не по умолчанию.

2) Создайте настраиваемую форму и вызовите для нее ShowDialog (). У меня это сработало, но другие сообщили, что это не работает. Вы также можете вызвать Show () и заблокировать себя (не забудьте вызвать Application.DoEvents (), чтобы он продолжал обрабатывать события).

person Martijn Stolk    schedule 19.04.2010