Я работаю над довольно крупным проектом, и его вряд ли поймают все. Я нашел событие, которое уведомляет меня о необработанных исключениях, однако я не нашел способ программно отключить диалоговое окно ошибок Windows. В идеале, если есть необработанное исключение, я хотел бы, чтобы это событие было запущено, предоставили диалоговое окно, сообщающее пользователю, что есть проблема, а затем, чтобы закрыть изящно. Есть какой-либо способ сделать это? Я понимаю, что могу обернуть самый высокий уровень в попытке поймать, но я надеялся на что-то более элегантное.Предотвратить «Отправить отчет об ошибке Microsoft»
ответ
Это то, что мы и сделали.
static void Main() {
try
{
SubMain();
}
catch (Exception e)
{
HandleUnhandledException(e);
}
}
private static void SubMain()
{
// Setup unhandled exception handlers
AppDomain.CurrentDomain.UnhandledException += // CLR
new UnhandledExceptionEventHandler(OnUnhandledException);
Application.ThreadException += // Windows Forms
new System.Threading.ThreadExceptionEventHandler(
OnGuiUnhandledException);
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.Run(new frmMain());
}
// CLR unhandled exception
private static void OnUnhandledException(Object sender,
UnhandledExceptionEventArgs e)
{
HandleUnhandledException(e.ExceptionObject);
}
// Windows Forms unhandled exception
private static void OnGuiUnhandledException(Object sender,
System.Threading.ThreadExceptionEventArgs e)
{
HandleUnhandledException(e.Exception);
}
http://msdn.microsoft.com/en-us/library/system.appdomain.unhandledexception.aspx
Хотя, если вы отпуская это как коммерческий проект, я призываю вас зарегистрироваться Microsoft, так что вы можете получить аварийные дампы и ошибки данные отчетностей, которая направляется в MS
Вы как-то ответили на свой вопрос. Лучший способ предотвратить появление ошибки - это написать код, который обрабатывает ваши исключения, поэтому диалог никогда не появится. Я бы сказал, что это предложит Раймонд Чен (если я могу быть таким смелым).
Глобальная попытка/улов (как и первый ответ) - это то, что я рассматривал. Я просто не был уверен, что это была лучшая практика или нет. Я также не был уверен, есть ли более чистый способ сделать это. – Steve
Вы можете попробовать играть с HKEY_LOCAL_MACHINE \ Software \ Microsoft \ Windows NT \ CurrentVersion \ AeDebug
Этот наконечник формы DrWatson дней .. может или не может работать.
Не обманывайте общесистемные настройки, если вы пытаетесь решить проблему, специфичную для приложения –
- пользователям может не понравиться тот факт, что вы меняете свои настройки ... - Возможно, у вашего приложения может быть доступ к записи в этот реестр ключ. –
Если ваш вопрос касался приложения WinForms, то выбранный ответ будет работать для вас, однако он не совсем изящный.
.NET предоставляет помощник для этого точного сценария:
Application.SetUnhandledExceptionMode(UnhandledExceptionMode.CatchException)
AddHandler AppDomain.CurrentDomain.UnhandledException, AddressOf CurrentDomain_UnhandledException
Если вы используете .NET Framework 2.0 или более позднюю версию, и есть необработанное исключение из рабочего потока, я верю тебе «Не повезло. В .NET 1.0 и 1.1 CLR просто проглотил исключение из потока, отличного от основного потока. Однако это было изменено в .NET 2.0, где необработанное исключение в потоке заставляет приложение отключиться.
Вы можете подписаться на AppDomain.CurrentDomain.UnhandledException, чтобы получить уведомление, когда происходят эти необработанные исключения, но приложение, скорее всего, завершает работу на этом этапе, и вам просто предоставляется возможность сделать что-то до неизбежного, например, протоколирования исключение где-то и отображение удобного для пользователя сообщения. UnhandledExceptionEventArgs имеет свойство readonly, называемое IsTermination, которое вы можете проверить, чтобы проверить, завершено ли приложение или нет. По завершении приложения обычно появляется диалоговое окно отчетов об ошибках Microsoft.
Хотя я бы не рекомендовал этого, есть способ вернуться к тому, как CLR 1.0 и 1.1 ведут себя, установив флаг совместимости приложений в файле конфигурации приложения.
Это не должно вызывать приложение прекратить в случае необработанных исключений и уменьшить вероятность получения этого диалогового окна сообщения об ошибке.
Моя рекомендация заключалась в том, чтобы поймать только те исключения, которые вы ожидаете и можете обрабатывать в своем коде, и пусть другие пузырится.
Это зависит от того, как вы управляете своими рабочими потоками. Мой предпочтительный подход для всех долгосрочных заданий - использовать Delegate.BeginInvoke() для использования потока ThreadPool для выполнения асинхронного действия. Если вы это сделаете, поток вернет любое исключение при вызове EndInvoke() - вам просто нужно убедиться, что EndInvoke вызывается для каждого BeginInvoke (это не может привести к утечкам ресурсов). – STW
Почему я получил downvoted? –
Почему вы реализуете как AppDomain.UnhandledException *, так и * завершаете все это в блоке Try/Catch? Это глупый гусь. –