90

これまでは、プログラムApplication.RunProgram.csエントリポイントの周りにtry/catchブロックを配置していました。これにより、デバッグモードですべての例外が十分にキャッチされますが、デバッグモードなしでプログラムを実行すると、例外が処理されなくなります。未処理の例外ボックスが表示されます。

私はこれが起こらないようにしたい。非デバッグモードで実行しているときにすべての例外をキャッチしたい。プログラムには複数のスレッドがあり、できればそれらのすべての例外が同じハンドラーによってキャッチされます。DBに例外を記録したい。誰かがこれを行う方法について何かアドバイスがありますか?

4

4 に答える 4

118

ThreadExceptionドキュメントの例を見てください。

public static void Main(string[] args)
{
   // Add the event handler for handling UI thread exceptions to the event.
    Application.ThreadException += new     
  ThreadExceptionEventHandler(ErrorHandlerForm.Form1_UIThreadException);

  // Set the unhandled exception mode to force all Windows Forms errors
  // to go through our handler.
  Application.SetUnhandledExceptionMode(UnhandledExceptionMode.CatchException);

  // Add the event handler for handling non-UI thread exceptions to the event. 
  AppDomain.CurrentDomain.UnhandledException += new       
  UnhandledExceptionEventHandler(CurrentDomain_UnhandledException);
}

また、デバッグが容易になるため、デバッグ時に例外をキャッチしないようにすることもできます。これは多少のハックですが、そのために上記のコードを次のようにラップすることができます

 if (!AppDomain.CurrentDomain.FriendlyName.EndsWith("vshost.exe")) { ... }

デバッグ時に例外がキャッチされないようにするため。

編集:ファイル名をチェックするよりもクリーンに感じるデバッガー内で実行されているアプリケーションをチェックする別の方法。

(meltedform、Kiquenet、Dougによるコメントを参照)

if(!System.Diagnostics.Debugger.IsAttached) { ... }

これにより、とは異なるデバッガーを使用する問題が回避されますvshost.exe

于 2011-04-23T07:04:35.407 に答える
27

NET 4では、特定の例外がデフォルトでキャッチされなくなりました。これらは、AccessViolationExceptionなど、実行可能ファイルの(おそらく致命的な)破損状態を示す例外になる傾向があります。

メインメソッドの前で[HandleProcessCorruptedStateExceptions]タグを使用してみてください。例:

using System.Runtime.ExceptionServices.HandleProcessCorruptedStateExceptions

[HandleProcessCorruptedStateExceptions]
public static int Main()
{
    try
    {
        // Catch any exceptions leaking out of the program
        CallMainProgramLoop();
    }
    catch (Exception e) // We could be catching anything here
    {
        System.Console.WriteLine(e.Message);
        return 1;
    }
    return 0;
  } 
于 2011-04-23T08:26:57.317 に答える
19

良い例はhttp://www.csharp-examples.net/catching-unhandled-exceptions/にあります。 基本的に、メインを次のように変更します。

static void Main()
    {
        Application.EnableVisualStyles();
        Application.SetCompatibleTextRenderingDefault(false);

        Application.ThreadException += new ThreadExceptionEventHandler(Application_ThreadException);
        Application.SetUnhandledExceptionMode(UnhandledExceptionMode.CatchException);
        AppDomain.CurrentDomain.UnhandledException += new UnhandledExceptionEventHandler(CurrentDomain_UnhandledException);

        Application.Run(new Form1());
    }

    static void Application_ThreadException(object sender, ThreadExceptionEventArgs e)
    {
        MessageBox.Show(e.Exception.Message, "Unhandled Thread Exception");
    }

    static void CurrentDomain_UnhandledException(object sender, UnhandledExceptionEventArgs e)
    {
        MessageBox.Show((e.ExceptionObject as Exception).Message, "Unhandled UI Exception");
    }
于 2015-11-12T11:42:51.147 に答える
9

そのためにNBugライブラリを使用できます。このような最小限のセットアップで:

NBug.Settings.Destination1 = "Type=Mail;From=me@mycompany.com;To=bugtracker@mycompany.com;SmtpServer=smtp.mycompany.com;";
AppDomain.CurrentDomain.UnhandledException += NBug.Handler.UnhandledException;
Application.ThreadException += NBug.Handler.ThreadException;

アプリケーションがクライアントにデプロイされている場合でも、アプリケーション内の未処理のすべてのバグに関する情報の収集を開始できます。サードパーティのライブラリを使用したくない場合は、以下のイベントに添付する必要があります。

// These two should come before enabling visual styles or running the application
AppDomain.CurrentDomain.UnhandledException += ...
Application.ThreadException += ...
...
Application.Run(new Form1());
于 2011-04-23T06:04:08.323 に答える