1

Application-Thread だけでなく、現在の AppDomain に対しても UnhandledExceptionMode.ThrowException を設定したいと考えています。別のスレッドからの例外も、CurrentDomain_UnhandledException イベント ハンドラーで処理する必要があります。これは可能ですか?これが私のコードです:

static class Program
{
    /// <summary>
    /// The main entry point for the application.
    /// </summary>
    [STAThread]
    static void Main()
    {
        Application.SetUnhandledExceptionMode(UnhandledExceptionMode.ThrowException);
        AppDomain.CurrentDomain.UnhandledException += new UnhandledExceptionEventHandler(CurrentDomain_UnhandledException);
        Application.EnableVisualStyles();
        Application.SetCompatibleTextRenderingDefault(false);
        Application.Run(new Form1());
    }

    static void CurrentDomain_UnhandledException(object sender, UnhandledExceptionEventArgs e)
    {
        File.AppendAllText("Log.txt", ((Exception)e.ExceptionObject).Message + Environment.NewLine);
    }
}
4

1 に答える 1

2

おそらく、によって提供される動作を探していますApplication.ThreadExceptionか? http://msdn.microsoft.com/en-us/library/system.windows.forms.application.threadexception%28v=vs.80%29.aspx

コメントによると、必要な動作を実現する 1 つの方法は、.Net 1 の古いハンドルされていない例外ポリシーを有効にすることです。

App.config で:

<runtime>
    <legacyUnhandledExceptionPolicy enabled="1" />
</runtime>

次に、メイン メソッドを次のように変更します。

class Program
{
    [STAThread]
    static void Main(string[] args)
    {
        try
        {
            AppDomain.CurrentDomain.UnhandledException += CurrentDomain_UnhandledException;

            ThreadPool.QueueUserWorkItem((object state) =>
            {
                throw new Exception("Exception thrown on Background Thread");
            });

            throw new Exception("Exception at the end of Main");
        }
        catch (Exception exception)
        {
            // Exceptions thrown on the Main Thread will pass through here
            HandleUnhandledException(exception);
        }
    }

    static void CurrentDomain_UnhandledException(object sender, UnhandledExceptionEventArgs e)
    {
        // Exceptions thrown on Background Threads will pass through here
        HandleUnhandledException((Exception)e.ExceptionObject);
    }

    static void HandleUnhandledException(Exception exception)
    {
        // TODO: Write your Unhandled Exception routine here
        Console.WriteLine(exception.Message);
    }
}

従来の例外ポリシーを有効にすると、バックグラウンド スレッドの例外がメイン スレッドによって無視されます。これらは、未処理の例外イベント リスナーによってのみ表示されます。.NET Unhandled Exception ダイアログが表示されないようにするには、メイン スレッドの例外を処理する必要がありますが、共有メソッドを使用すると、例外処理コードを再利用できます。


AppDomain.UnhandledException アタッチするイベント ハンドラーは、AppDomain. 図から Windows-Forms を削除すると、それを示すコードが次のようになります。

class Program
{
    [STAThread]
    static void Main(string[] args)
    {
        AppDomain.CurrentDomain.UnhandledException += CurrentDomain_UnhandledException;

        ThreadPool.QueueUserWorkItem((object state) =>
        {
            throw new Exception("Exception thrown on Background Thread");
        });

        throw new Exception("Exception at the end of Main");
    }

    static void CurrentDomain_UnhandledException(object sender, UnhandledExceptionEventArgs e)
    {
        Console.WriteLine(((Exception)e.ExceptionObject).Message);
    }
}

これを実行すると、 の最後にある未処理の例外が原因でアプリケーションがクラッシュする直前に、両方の例外メッセージがコンソールに書き込まれることがわかりますMain。(:これは、イベント ハンドラーが両方の例外に対して機能することを示していますが、競合状態があります。実際には、未処理の例外はAppDomain次の例外が発生する前に強制終了します)

于 2014-10-17T11:28:52.857 に答える