2012-05-11 22 views
4

私はプログラムのメインクラスでCで未処理の例外をキャッチする方法は?

static class Program 
{ 
/// <summary> 
/// The main entry point for the application. 
/// </summary> 
[STAThread] 
static void Main() 
{ 
Application.EnableVisualStyles(); 
Application.SetCompatibleTextRenderingDefault(false); 

AppDomain.CurrentDomain.UnhandledException += new UnhandledExceptionEventHandler(CurrentDomain_UnhandledException); 

Application.Run(new Form1()); 
} 


public static void CurrentDomain_UnhandledException(Object sender, UnhandledExceptionEventArgs e) 
{ 

MessageBox.Show((e.ExceptionObject as Exception).Message, "Unhandled domain Exception"); 
Application.Exit(); 
} 

をこのコードを使用して、私のプログラム内の任意のunhandeled例外をキャッチしようとしているが、今の私のフォームForm1のイム、私はシンプルな例外を作成しよう:なし、ゼロによる除算をtry catchブロックでは、メインモジュールのコードが実際に例外をインターセプトしますが、私はまだMS Visual Studioダイアログを持っています。アプリケーションは終了しません。実際の状況ではもちろん、私はエラーをログ/メールします。しかし私は私の例外を傍受した後に実行がなぜ続くのか理解したいと思いますか?メインUIスレッドからのすべての例外をキャッチおかげで

+0

Application.Exit()の代わりにEnvironment.Exit()を使用します。 –

答えて

9

私の仕事:

static class Program 
    { 
     /// <summary> 
     /// The main entry point for the application. 
     /// </summary> 
     [STAThread] 
     static void Main() 
     { 
      Application.EnableVisualStyles(); 
      Application.SetCompatibleTextRenderingDefault(false); 

      // Add handler for UI thread exceptions 
      Application.ThreadException += new ThreadExceptionEventHandler(UIThreadException); 

      // Force all WinForms errors to go through handler 
      Application.SetUnhandledExceptionMode(UnhandledExceptionMode.CatchException); 

      // This handler is for catching non-UI thread exceptions 
      AppDomain.CurrentDomain.UnhandledException += new UnhandledExceptionEventHandler(CurrentDomain_UnhandledException); 

      Application.Run(new Form1()); 
     } 

     private static void CurrentDomain_UnhandledException(Object sender, UnhandledExceptionEventArgs e) 
     { 
      try 
      { 
       Exception ex = (Exception)e.ExceptionObject; 
       MessageBox.Show("Unhadled domain exception:\n\n" + ex.Message); 
      } 
      catch (Exception exc) 
      { 
       try 
       { 
        MessageBox.Show("Fatal exception happend inside UnhadledExceptionHandler: \n\n" 
         + exc.Message, "", MessageBoxButtons.OK, MessageBoxIcon.Stop); 
       } 
       finally 
       { 
        Application.Exit(); 
       } 
      } 

      // It should terminate our main thread so Application.Exit() is unnecessary here 
     } 

     private static void UIThreadException(object sender, ThreadExceptionEventArgs t) 
     { 
      try 
      { 
       MessageBox.Show("Unhandled exception catched.\n Application is going to close now."); 
      } 
      catch 
      { 
       try 
       { 
        MessageBox.Show("Fatal exception happend inside UIThreadException handler", 
         "Fatal Windows Forms Error", MessageBoxButtons.AbortRetryIgnore, MessageBoxIcon.Stop); 
       } 
       finally 
       { 
        Application.Exit(); 
       } 
      } 

      // Here we can decide if we want to end our application or do something else 
      Application.Exit(); 
     } 
    } 
0
Use Environment.Exit() 

代わり

Application.Exit() 
1

あなたはApplication.ExitまたはEnvironment.Exitを使用する必要はありませんで、これはビジュアルスタジオの動作であり、傍受して未処理の例外を引き起こしますが、実際には、isTerminatingフラグがセットされているとアプリケーションがクラッシュ(終了)することになります。これがiの正しい使い方ですt、私はこのイベントや他のリソースを必要とするユーザインタフェースを使用しないことをお勧めします。

このイベントの目的は、正確に起こった理由をログに記録することです。これは、アプリケーションがクラッシュしている間に見栄えを良くするためのポイントではなく、このことについてユーザーに謝罪します。あなたが次回にログインしたときに上記を行う機会があります。

したがって、例外ログを電子メールで送信する予定がある場合でも、ファイルを書き、アプリケーションの次回の起動時にそのファイルを電子メールで送信することをお勧めします。

私は通常log4netを使い、以下のようなイベントを使います。

[STAThread] 
static void Main() 
{ 
    log.Info("Starting deployer application"); 

    Application.ThreadException += new System.Threading.ThreadExceptionEventHandler(Application_ThreadException); 
    AppDomain.CurrentDomain.UnhandledException += new UnhandledExceptionEventHandler(CurrentDomain_UnhandledException); 
    Application.ApplicationExit += new EventHandler(Application_ApplicationExit); 

    Application.Run(ConnectionForm.GetInstance); 
} 

static void Application_ApplicationExit(object sender, EventArgs e) 
{ 
    log.Info("Application Closed"); 
} 

static void CurrentDomain_UnhandledException(object sender, UnhandledExceptionEventArgs e) 
{ 
    log.Error(string.Format("*** UNHANDLED APPDOMAIN EXCEPTION ({0}) *****", e.IsTerminating ? "Terminating" : "Non-Terminating"), e.ExceptionObject as Exception); 
} 

static void Application_ThreadException(object sender, System.Threading.ThreadExceptionEventArgs e) 
{ 
    log.Error("*** UNHANDLED THREAD EXCEPTION *****", e.Exception); 
} 

this can be helpfulより前にlog4netを使用したことがない場合。

関連する問題