質問: ### 前提・実現したいこと WPFのアプリケーションで発生する例外がUnhandledExceptionでキャッチできず、 アプリケーションの停止を引き起こしてしまいます。 どうにかキャッチしてログを出力したいのですが、 デバッグ実行できる環境ではないため発生している箇所もわからず対策が取れません。 UnhandledExceptionでキャッチできずアプリケーションが停止する例外には、 どのようなものがありますでしょうか? ### 該当のソースコード UnhandledExceptionイベントには下記のように処理を登録しています。 ``` public partial class App : Application { private void Application_Startup(object sender, StartupEventArgs e) { AppDomain.CurrentDomain.UnhandledException += this.CurrentDomain_UnhandledException; } private void CurrentDomain_UnhandledException(object sender, UnhandledExceptionEventArgs e) { try { if (e.ExceptionObject is Exception ex) { // ログ出力 MessageBox.Show(string.Concat(ex.Message, ex.StackTrace)); } } finally { Current.Shutdown(); } } } ```
回答: 基本的にはUIスレッド外で発生した例外が`UnhandledException`になります。 例えば次のコードのように別スレッドで例外をスローすれば発生します。 ``` private void Button_Click(object sender, RoutedEventArgs e) { Thread th = new Thread(DoWork); th.Start(); } private void DoWork(object obj) { throw new NotImplementedException(); } ``` > > WPFのアプリケーションで発生する例外がUnhandledExceptionでキャッチ > > > `App.xaml.cs`で次のコードのように`Startup`イベントで`UnhandledException`の例外集約ハンドラを追加できます。つまり`UnhandledException`をキャッチできます。 ``` public partial class App : Application { private void Application_Startup(object sender, StartupEventArgs e) { AppDomain.CurrentDomain.UnhandledException += CurrentDomain_UnhandledException; } void CurrentDomain_UnhandledException(object sender, UnhandledExceptionEventArgs e) { Exception ex = e.ExceptionObject as Exception; MessageBox.Show(ex.Message, "例外発生(UI スレッド外)", MessageBoxButton.OK, MessageBoxImage.Error); this.Shutdown(); } } ``` `App.xaml`に`Startup`のイベントハンドラを登録します ``` ``` `Startup="Application_Startup"`を追加しただけです。 これでボタンを押せばUnhandledExceptionが発生して、例外集約ハンドラにてキャッチされ、メッセージボックスが表示されるようになります。 !UnhandledExceptionをキャッチ 参考: