У меня проблема. Один из пользователей приложения, которое я разрабатываю, время от времени, но регулярно испытывает зависание приложения.
Когда это происходит, мы находим запись с источником «Application Hang» в журнале событий машины с информативным сообщением «Зависание приложения [мое приложение], версия [правильная версия], модуль зависания hangapp, версия 0.0» .0.0, адрес зависания 0x00000000. "
Я регистрирую все необработанные исключения, которые выбрасывает мое приложение, и в моих файлах журналов нет записей, когда это происходит.
Моя текущая рабочая гипотеза состоит в том, что это зависание происходит во время вызова приложения небезопасного устаревшего API. Это не удивило бы меня; Я работал с этим API в течение многих лет, и хотя я не видел, чтобы он зависал раньше, это действительно дрянной код. Также пользователь сообщает, что программа, кажется, зависает в случайное время. Я не думаю, что это действительно так. Не то, чтобы я ей не поверил, а в том, что код, который общается с унаследованным API, работает внутри метода, вызываемого BackgroundWorker. Если бы фоновый поток вызывал зависание приложения, это могло бы очень сильно показаться пользователю случайным.
Итак, у меня есть два вопроса, один конкретный, один общий.
Конкретный вопрос: я ожидаю, что если метод, работающий в потоке, не являющемся пользовательским интерфейсом, зависнет, он просто уничтожит поток. Будет ли это на самом деле убить все приложение?
Общий вопрос:
Я уже регистрирую все необработанные исключения. Моя программа уже настроена на использование трассировки (хотя мне нужно добавить инструментарий для отслеживания активности в подозрительных методах). Есть ли другие вещи, которые я должен делать? Существуют ли диагностические инструменты, позволяющие проводить анализ после сбоя при зависании приложения .NET? Существуют ли в платформе .NET механизмы, которые я могу задействовать для сбора дополнительных (и более полезных) данных?
РЕДАКТИРОВАТЬ: При более внимательном рассмотрении моего кода я вспоминаю, что все его использование BackgroundWorker осуществляется через реализованный мной служебный класс, который оборачивает метод, вызываемый в обработчике исключений. Этот обработчик регистрирует исключение, а затем возвращает его как свойство объекта утилиты. Обработчик события завершения в потоке пользовательского интерфейса перебрасывает исключение (менее чем идеально, поскольку я теряю стек вызовов, но он уже был зарегистрирован), в результате чего основной обработчик исключений пользовательского интерфейса сообщает об исключении в окно сообщения, а затем завершает приложение.
Поскольку ничего этого не происходит, я вполне уверен, что в фоновом потоке нет исключений. Ну, в любом случае, нет .NET исключения.
Дальнейшее наблюдение:
К счастью, я получил достаточно данных от пользователей, чтобы быть уверенным, что зависание не происходит в устаревшем API. Это означает, что я явно что-то не так делаю, а это значит, что я могу это исправить, так что выиграть. Это также означает, что я могу изолировать проблему с помощью отслеживания, что является еще одной победой. Я очень рад ответам, которые я получил на этот вопрос; Я даже счастлив, что мне, вероятно, не нужны они для этой проблемы.
Также: PostSharp выдающийся. Если вам нужно добавить код инструментария в существующее приложение, вы почти наверняка должны его использовать.