как избежать сбоя экрана Windows - PullRequest
2 голосов
/ 25 февраля 2011

У нас есть UnhandledExceptionEventHandler, и этот обработчик обнаружил непредвиденные исключения.Но почему мы все еще видим следующий экран?Я думал, что если мы обработаем исключение, оно не поднимется до ОС.Если никакие исключения не достигают системного уровня, почему этот экран все еще отображается?

enter image description here

Ответы [ 4 ]

7 голосов
/ 25 февраля 2011

Регистрация UnhandledExceptionEventHandler с помощью AppDomain.UnhandledException не означает, что необработанные исключения становятся обработанными.Вместо этого это механизм, позволяющий регистрировать исключение и соответствующее состояние программы, чтобы помочь в дальнейшей отладке.Исключение останется необработанным, и будет генерироваться отчет об ошибках Windows.

В действительности, когда вызывается это событие, «слишком поздно» для обработки исключения.Предполагая, что вы можете указать среде выполнения продолжить выполнение, куда будет выполняться выполнение?Ни один кадр в стеке вызовов не хотел обрабатывать исключение.В лучшем случае исполняющий поток может быть прерван;но что, если это единственный поток переднего плана?Лучше распространить необработанное исключение на фильтр необработанных исключений по умолчанию операционной системы и позволить ему вызывать отчеты об ошибках Windows.

Редактировать с некоторыми дополнительными комментариями:
Теперь некоторые приложения, которые вы хотите создать, будут устойчивыми к сбоямнапример, длительные процессы обслуживания.В некоторых случаях может иметь смысл добавить обработчики исключений «catch-all» *, например, очередь заданий, которая выполняет задания, и не имеет значения, если отдельное задание не выполнено с необработанным исключением;мы регистрируем проблему и переходим к следующей работе.Тем не менее, обработчик корня всеохватывающего типа в Main не имеет смысла: все ваше приложение теперь находится в неизвестном состоянии.Вы можете зарегистрировать исключение и прекратить работу, но вы не сможете воспользоваться преимуществами отчетов об ошибках Windows: посмертные мини-дампы и простая кнопка (кнопка «Отладка» в этом диалоговом окне) для вызова зарегистрированного отладчика JIT, который приметВы прямо к проблеме.Для большинства программ мой совет - просто позволить вашему программному обеспечению рухнуть;Ошибки in-your-face с мини-дампами, как правило, являются одними из самых простых для исправления.

* Некоторые исключения по своей сути являются "неуловимыми", например StackOverflowException.Другие, такие как AccessViolationException, являются перехватываемыми, но по своей сути указывают на серьезное несоответствие состояния программы (не удалось прочитать или записать из ожидаемой области памяти).Никогда не стоит пытаться восстанавливаться после таких исключений.

1 голос
/ 25 февраля 2011

Это потому, что ваше необработанное исключение возникает в главном потоке, и с этим почти ничего не поделать.Проверьте эту статью: Что !?Приложение .NET может умереть?

Почти ничего, да, потому что вы все еще можете поймать это исключение на уровне Application.Run.На данный момент ваше приложение все равно не работает, но вы можете, по крайней мере, «избежать экрана сбоя Windows» и вместо этого реализовать собственный экран сбоя:

    static void Main()
    {
        try
        {
            Application.Run(new Form1());
        }
        catch (Exception ex)
        {
            MessageBox.Show("Oops! Can I has " + ex.Message + "?");
        }
    }
1 голос
/ 25 февраля 2011

Нажмите кнопку «Отладка», чтобы увидеть, откуда возникло исключение.

Если вы не видите его сразу, запустите приложение в Visual Studio, перейдите в диалоговое окно «Отладка, исключения» и проверьте все исключения. Затем перезапускайте приложение, исследуйте код каждый раз, когда отладчик сообщает вам, что возникла исключительная ситуация первого шанса, и передайте это исключение приложению, если Visual Studio спросит вас, нужно ли это сделать.

Это должно помочь вам найти источник проблемы.

0 голосов
/ 25 февраля 2011

В некоторых случаях UnhandledExceptionEventHandler не обрабатывает неэкранированные исключения.Например, System.Timers.Timer поглощает исключения, поэтому они не передаются в UnhandledExceptionEventHandler.

...