2017-02-22 26 views
0

У меня есть простое приложение WinForms, работающее с BackgroundWorker.BackroundWorker - Исключение - не закрывать приложение WinForms

Ниже Главная, где я прикрепляю обработчики исключений.

static class Program 
{ 
    private static Logger _logger = LogManager.GetCurrentClassLogger(); 

    /// <summary> 
    /// The main entry point for the application. 
    /// </summary> 
    [STAThread] 
    static void Main() 
    { 
     Application.ThreadException += OnThreadException; 
     //Application.SetUnhandledExceptionMode(UnhandledExceptionMode.CatchException); 
     // AppDomain.CurrentDomain.UnhandledException += OnUnhandledException; 

     Application.EnableVisualStyles(); 
     Application.SetCompatibleTextRenderingDefault(false); 

     try 
     { 
      Application.Run(new Form()); 
     } 
     catch (Exception exc) 
     { 
      LogFatalException(exc); 
     } 
    } 

    private static void OnUnhandledException(object sender, UnhandledExceptionEventArgs e) 
    { 
     if (e.IsTerminating) 
     { 
      _logger.Info("Application is terminating due to an unhandled exception in a secondary thread."); 
     } 
     LogFatalException(e.ExceptionObject as Exception); 
    } 

    private static void OnThreadException(object sender, ThreadExceptionEventArgs e) 
    { 
     LogFatalException(e.Exception); 
    } 

    private static void LogFatalException(Exception exc) 
    { 
     _logger.Error(exc, exc.Message); 

     MessageBox.Show(exc.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error); 
    } 
} 

Я звоню в свой рабочий стол, как показано ниже. Я хочу, чтобы какой-либо тип исключения происходил в фоновом потоке, чтобы перейти к основным методам обработки и log/alert, но НЕ закрыл приложение.

Что я делаю неправильно? Приложение все еще закрывается.

backgroundWorker1.RunWorkerCompleted += (senderWorker, eWorker) => 
{ 
    if (eWorker != null) 
    { 
     throw new Exception("Error Processing. Please check connection and try again."); 
    } 
}; 

backgroundWorker1.RunWorkerAsync(); 
+0

Если вы не поймать, что исключение где-то структура будет прекратить применение. –

+0

Питер, можете ли вы более конкретно на основе кода, который я изложил? Где я должен ловить исключение? – aherrick

+0

Почему отмечена подписка UnhandledException? –

ответ

0

Если вы позволите пузырек исключения вплоть до тех пор, даже не покинет Application.Run() вызова, то, очевидно, это Application не может работать больше, вы поймали исключение вне сферы охвата Application «s. Вам нужно будет поймать исключение внутри ваш Form.

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

Аргумент этого обработчика eWorker предоставляется посредством реализации BackgroundWorker. Вы можете надеяться, что это никогда не будет null. Что вы можете проверить, это свойство ResulteWorker. Это будет зависеть от того, что вы установили в свойстве ResultDoWorkEventArgs, которое вы получили в качестве аргумента для вашего обработчика DoWork.

Так, например:

backgroundWorker1.RunWorkerCompleted += (senderWorker, eWorker) => 
{ 
    if (eWorker.Result != null) 
    { 
     MessageBox.Show("Process result: " + eWorker.Result.ToString()) 
    } 
} 

и ваш DoWork обработчик может выглядеть следующим образом:

backgroundWorker1.DoWork += (senderWorker, e) => 
{ 
    try 
    { 
     // do something that might throw an exception 
    } 
    catch(Exception exception) 
    { 
     e.Result = exception; // this result is passed on to RunWorkerCompleted event 
    } 
}