none
Глобальная обработка исключений RRS feed

  • Вопрос

  • Всем привет!
    Есть небольшой вопрос - как реализовать глобальный обработчик исключений в приложении, так как приложении достаточно громоздкое и очень много мест где оно может грохнуться, а оборачивать каждую проблемную точку в try ... catch ... finally - в итоге не очень красиво. Да и собственно ради тренировки мозгов интересно как нормально такое сделать =)
    Перелопатил кучу инфы в инете и на MSDN - накопал такие две штуки

    AppDomain.CurrentDomain.UnhandledException
    

    и

    Application.ThreadException
    

    Судя по докам на МСДН с помощью первой можем перехватить необработанные исключения в текущем домене приложений и с помощью второго хватать исключения в приложениях с GUI потоком. собственно вот что в итоге получилось, в точку входа приложения добавляем эти инструкции, там же добавляем метод который будет обрабатывать исключения и задаем правило что делать при возникновение необработанного исключения:

    static class Program
      {
        /// <summary>
        /// The main entry point for the application.
        /// </summary>
        [STAThread]
        [SecurityPermission(SecurityAction.Demand, Flags = SecurityPermissionFlag.ControlAppDomain)]
    .    static void Main()
    .    {
    .      Application.ThreadException += new System.Threading.ThreadExceptionEventHandler(MyExceptionHandler);
          Application.SetUnhandledExceptionMode(UnhandledExceptionMode.CatchException, true);
          AppDomain.CurrentDomain.UnhandledException += new UnhandledExceptionEventHandler(CurrentDomain_UnhandledException);
     
          Application.EnableVisualStyles();
          Application.SetCompatibleTextRenderingDefault(false);
          Application.Run(new ClientMainForm());
        }
     
        static void MyExceptionHandler(object sender, ThreadExceptionEventArgs e)
        {
          MessageBox.Show(e.Exception.Message);
        }
     
        static void CurrentDomain_UnhandledException(object sender, UnhandledExceptionEventArgs args)
        {
          using (ThreadExceptionDialog exceptionDlg = new ThreadExceptionDialog((Exception)args.ExceptionObject))
          {
            exceptionDlg.ShowDialog();
          }
        }
      }
    
    

    и все хорошо, исключения ловится через AppDomain, если бы не одно но - после закрытие моего месседжбокс или диалога который я вызывваю в методе обработки все равно вываливается ошибка в код (при отладке) или потом вылазит стандартное окно фраимворка и винды про ошибку (при запуска exe файла).
    искал всего кучу, но все итоге сводится к этому же. находил еще где то что бы Application.ThreadException работала на нескольких потоках но все равно - ошибка ловится а потом все равно вылизат.

    я хочу попробовать добиться сокращения блоков try ... catch в коде, заменив из на глобальный обработчик исключений, в который это все будет стекаться. То есть допустим у меня есть кусок кода, в котором идут инструкции по обращению к удаленной службе и с ожидание кого то ответа. этот блок кода я оборачиваю в try ... catch, и если например служба недоступна или еще что то до ловится исключение. выводится инфа об ошибке,и приложения остается работать дальше просто не получив ожидаемого ответа. вот, а таких кусков кода которые надо обернуть в try ... catch много и они однотипны, вот я и хотел сделать так что бы стоял глобальный обработчик, в котором был бы метод которой задавал повеление при том или ином типе исключения, допустив выдавал месседжбокс с инфой про исключение и приложение не выдавая никаких критических ошибок оставалась в рабочем состояние дальше. как при оборачивании критических кусков в try .. catch. вот собственно так.

    в некоторых доках увидел фразы типа "AppDomain.... это способ залогировать ошибку. при этом приложение уже упало..."

    а как сделать так чтобы приложение не падало? то ест как try .. catch на глобальном уровне без оборачивание куска

          Application.EnableVisualStyles();
          Application.SetCompatibleTextRenderingDefault(false);
          Application.Run(new ClientMainForm());
    
    

    в try ... catch ?

    спасибо

     

     

     

     

     

    3 марта 2011 г. 9:41

Ответы

Все ответы