.Нетто - какой самый лучший способ реализации "перехватывать все исключения обработчик"
Мне интересно, что лучший способ-это "если ничего не поймаешь".
Я имею в виду, что вы обрабатываете как можно больше исключений в своем приложении, но все равно обязательно будут ошибки, поэтому мне нужно что-то, что ловит все необработанные исключения, чтобы я мог собирать информацию и хранить их можно поместить в базу данных или отправить в веб-службу.
делает AppDomain.CurrentDomain.UnhandledException событие захватить все? Даже если приложение многопоточность?
Примечание стороны: Windows Vista предоставляет собственные функции API, которые позволяют любое приложение чтобы восстановить себя после аварии... не могу сейчас вспомнить имя... но я бы не хотела используйте его, так как многие из наших пользователей все еще используют Windows XP.
9 ответов:
Я только что играл с поведением UnhandledException AppDomain, (это последний этап, на котором регистрируется необработанное исключение)
Да, после обработки обработчиков событий ваше приложение будет прекращено и противно"... программа перестала работать диалоговое окно " показано.
:) Ты еще можно избежать.
проверить:
class Program { void Run() { AppDomain.CurrentDomain.UnhandledException += new UnhandledExceptionEventHandler(CurrentDomain_UnhandledException); Console.WriteLine("Press enter to exit."); do { (new Thread(delegate() { throw new ArgumentException("ha-ha"); })).Start(); } while (Console.ReadLine().Trim().ToLowerInvariant() == "x"); Console.WriteLine("last good-bye"); } int r = 0; void CurrentDomain_UnhandledException(object sender, UnhandledExceptionEventArgs e) { Interlocked.Increment(ref r); Console.WriteLine("handled. {0}", r); Console.WriteLine("Terminating " + e.IsTerminating.ToString()); Thread.CurrentThread.IsBackground = true; Thread.CurrentThread.Name = "Dead thread"; while (true) Thread.Sleep(TimeSpan.FromHours(1)); //Process.GetCurrentProcess().Kill(); } static void Main(string[] args) { Console.WriteLine("..."); (new Program()).Run(); } }
П. С. do обрабатывать необработанные для применения.Threadexceptionметод (WinForms) или DispatcherUnhandledException (WPF) на более высоком уровне.
In ASP.NET, вы используете на .
в WinForms, вы используете
MyApplication_UnhandledException
наApplicationEvents
fileобе эти функции вызываются, если необработанное исключение возникает в коде. Вы можете зарегистрировать исключение и представить приятное сообщение пользователю из этих функций.
для приложений Winform, в дополнение к AppDomain.CurrentDomain.UnhandledException я также использую приложение.Threadexceptionметод и приложение.SetUnhandledExceptionMode (w / UnhandledExceptionMode.CatchException). Эта комбинация, кажется, ловит все.
В основном потоке у вас есть следующие параметры:
- консоль или приложение-служба:
AppDomain.CurrentDomain.UnhandledException
- приложение WinForms:
Application.ThreadException
- веб-приложение: глобальный.эйсакс это
Application_Error
на другие темы:
- вторичные потоки не имеют необработанных исключений; используйте SafeThread
- рабочие потоки: (таймер, threadpool) нет никакой сети безопасности на все!
имейте в виду, что эти события не дескриптор исключения, они просто отчет их приложения-часто, когда это слишком поздно, чтобы сделать что-нибудь полезное/вменяемое о них
ведение журнала исключений хорошо, но мониторинг приложений лучше ; -)
предостережение: я являюсь автором SafeThread статьи.
для WinForms не забудьте прикрепить к событию необработанного исключения текущего потока (особенно если вы используете многопоточность).
некоторые ссылки на лучшие практики здесь и здесь и здесь (вероятно, лучшая статья обработки исключений для .net)
есть также классная вещь под названием ELMAH что будет регистрировать любой ASP.NET ошибки, возникающие в веб-приложении. Я знаю, что вы спрашиваете о решении приложения Winform, но я чувствовал, что это может быть полезно для всех, кому нужны такие вещи в веб-приложении. Мы используем его там, где я работаю, и это было очень полезно при отладке (особенно на производственных серверах!)
вот некоторые функции, которые он имеет (вытащил прямо со страницы):
- Регистрация почти все необработанные исключения.
- веб-страница для удаленного просмотра всего журнала перекодированных исключений.
- веб-страница для удаленного просмотра полной информации о любом зарегистрированном исключении.
- во многих случаях, вы можете просмотреть оригинальный желтый экран смерти, что ASP.NET созданный для данного исключение, даже в режиме customErrors выключенный.
- уведомление по электронной почте о каждой ошибке в момент ее возникновения.
- RSS-канал последние 15 ошибок из журнала.
- ряд реализаций резервного хранилища для журнала, в том числе в памяти, Microsoft SQL Server и несколько сообществом.
вы можете отслеживать большинство исключений в этом обработчике даже в многопоточных приложениях, но .NET (начиная с 2.0) не позволит вам отменить необработанные исключения, если вы не включите режим совместимости 1.1. Когда это произойдет, домен приложений будет закрыт, несмотря ни на что. Лучшее, что вы можете сделать, это запустить приложение в другом домене приложений, чтобы вы могли обработать это исключение и создать новый домен приложений для перезапуска приложения.
Я использую следующий подход, который работает и значительно уменьшает количество кода, ( но я не уверен, если есть лучший способ, или какие подводные камни могут быть. Всякий раз, когда вы звоните: Я сомневаюсь, что quys, дающие минусы, будут достаточно вежливы, чтобы прояснить их действия;)
try { CallTheCodeThatMightThrowException() } catch (Exception ex) { System.Diagnostics.StackTrace st = new System.Diagnostics.StackTrace (); Utils.ErrorHandler.Trap ( ref objUser, st, ex ); } //eof catch
и вот код ErrorHandler : Просто чтобы прояснить -: objUser-это объект, моделирующий приложения (вы можете получить информацию , такую как доменное имя , отдел, регион и т. д. для ведения журнала цели Выйти из кратера Регистратор - является объектом регистрации, например, одна осуществляющие деятельность в области лесозаготовок StackTrace st-объект StackTrace, дающий вам отладочную информацию для вашего приложения
using System; using log4net; //or another logging platform namespace GenApp.Utils { public class ErrorHandler { public static void Trap ( Bo.User objUser, ILog logger, System.Diagnostics.StackTrace st, Exception ex ) { if (ex is NullReferenceException) { //do stuff for this ex type } //eof if if (ex is System.InvalidOperationException) { //do stuff for this ex type } //eof if if (ex is System.IndexOutOfRangeException) { //do stuff for this ex type } //eof if if (ex is System.Data.SqlClient.SqlException) { //do stuff for this ex type } //eof if if (ex is System.FormatException) { //do stuff for this ex type } //eof if if (ex is Exception) { //do stuff for this ex type } //eof catch } //eof method }//eof class } //eof namesp
в приложении с графическим интерфейсом manged по умолчанию исключения, возникающие в потоке GUI, обрабатываются тем, что назначено приложению.Threadexceptionметод.
исключения, которые возникают в других потоках, обрабатываются AppDomain.CurrentDomain.событие UnhandledException.
Если вы хотите, чтобы ваши исключения потока GUI работали так же, как ваши-не GUI, так что они обрабатываются AppDomain.CurrentDomain.UnhandledException, вы можете сделать это:
Application.SetUnhandledExceptionMode(UnhandledExceptionMode.ThrowException);
An преимущество для перехвата исключений GUI thread с помощью ThreadException заключается в том, что вы можете использовать параметры, позволяющие приложению продолжать работу. Чтобы убедиться, что никакие файлы конфигурации не переопределяют поведение по умолчанию, вы можете вызвать:
Application.SetUnhandledExceptionMode(UnhandledExceptionMode.CatchException);
вы все еще уязвимы для исключений из плохо себя ведут собственные DLL. Если собственная dll устанавливает свой собственный обработчик с помощью Win32 SetUnhandledExceptionFilter, он должен сохранить указатель на предыдущий фильтр и вызвать его тоже. Если это не так что ваш обработчик не вызывается.