Как уловить ВСЕ исключения/сбои в приложении .NET
Возможный дубликат:
.NET - Каков наилучший способ реализации "улавливать все обработчики исключений"
У меня есть приложение консольного приложения .NET, которое сбой и отображение сообщения пользователю.
Весь мой код находится в блоке try{<code>} catch(Exception e){<stuff>}
, но иногда появляются ошибки.
В приложении Win32 вы можете записывать все возможные исключения/сбои, устанавливая различные обработчики исключений:
/* C++ exc handlers */
_set_se_translator
SetUnhandledExceptionFilter
_set_purecall_handler
set_terminate
set_unexpected
_set_invalid_parameter_handler
Что такое эквивалент в мире .NET, поэтому я могу обрабатывать/записывать/блокировать все возможные случаи ошибок?
Ответы
Ответ 1
Вопреки тому, что опубликовали некоторые другие, нет ничего плохого в том, чтобы ловить все исключения. Важно, чтобы они справлялись с ними должным образом. Если у вас возникло переполнение стека или из памяти, приложение должно быть закрыто для них. Кроме того, имейте в виду, что условия OOM могут помешать вашему обработчику исключений работать правильно. Например, если ваш обработчик исключений отображает диалоговое окно с сообщением об исключении, если у вас недостаточно памяти, для отображения диалогового окна может быть недостаточно. Лучше всего зарегистрировать его и немедленно закрыть.
Как уже упоминалось, существуют события UnhandledException и ThreadException, которые вы можете обрабатывать для исключений коллекции, которые в противном случае могли бы быть пропущены. Затем просто бросьте обработчик исключений вокруг вашего основного цикла (при условии приложения winforms).
Кроме того, вы должны знать, что OutOfMemoryExceptions не всегда выбрасываются из-за нехватки памяти. Условие OOM может запускать всевозможные исключения, в вашем коде или в структуре, которые не обязательно имеют какое-либо отношение к тому факту, что реальное основное условие не имеет памяти. Я часто видел InvalidOperationException или ArgumentException, когда основная причина на самом деле была не в памяти.
Ответ 2
Вы можете добавить обработчик события в событие AppDomain.UnhandledException, и он будет вызываться, когда исключение будет выбрано и не поймано.
Ответ 3
Эта статья в кодепере нашего хоста Jeff Atwood - вот что вам нужно.
Включает код для обнаружения необработанных исключений и лучших оценок для отображения информации о сбое пользователю.
Ответ 4
Класс Global.asax - это ваша последняя линия защиты.
Посмотрите:
protected void Application_Error(Object sender, EventArgs e)
Метод
Ответ 5
Имейте в виду, что какое-то исключение опасно для улова - или в основном несовместимо,
- OutOfMemoryException: все, что вы делаете в обработчике catch, может выделять память (на управляемой или неуправляемой стороне CLR) и, таким образом, запускать другой OOM
- StackOverflowException: в зависимости от того, обнаружена ли CLR достаточно рано, вы можете получить уведомление. В худшем случае это просто убивает процесс.
Ответ 6
Вы можете использовать AppDomain.CurrentDomain.UnhandledException, чтобы получить событие.
Ответ 7
Хотя перехватывать все исключения без плана для их правильной обработки, безусловно, является плохой практикой, я думаю, что приложение должно потерпеть неудачу каким-то изящным способом. Авария не должна напугать пользователя до смерти, и, по крайней мере, он должен отображать описание ошибки, некоторую информацию для отчета в службу технической поддержки и, в идеале, кнопку, чтобы закрыть приложение и перезапустить его. В идеальном мире приложение должно иметь возможность сбросить на диск пользовательские данные, а затем попытаться восстановить его (но я вижу, что это слишком много).
Во всяком случае, я обычно использую:
AppDomain.CurrentDomain.UnhandledException
Ответ 8
Вы также можете перейти с событием Application.ThreadException.
Как только я разрабатывал приложение .NET, работающее внутри приложения на основе COM; это событие было очень полезным, поскольку AppDomain.CurrentDomain.UnhandledException в этом случае не работало.
Ответ 9
Я думаю, вам лучше не поймать все Исключение, но лучше дать им показать пользователю. Причиной этого является то, что вы должны поймать только Исключения, которые вы действительно можете обработать. Если вы столкнетесь с некоторыми исключениями, которые заставляют программу остановиться, но все равно поймать ее, это может вызвать гораздо более серьезные проблемы.
Также читайте FAQ: Почему FxCop предупреждает об уловке (исключение)?.
Ответ 10
Помните, что улавливание этих необработанных исключений может изменить требования безопасности вашего приложения. Приложение может перестать работать в определенных контекстах (при запуске из сетевого ресурса и т.д.). Обязательно тщательно протестируйте.
Ответ 11
не больно использовать оба AppDomain.CurrentDomain.UnhandledException Application.ThreadException
но имейте в виду, что исключения из вторичных потоков не пойманы этими обработчиками; используйте SafeThread для дополнительных потоков при необходимости