アプリの終了間際に発生するイベント
AppDomain.UnhandledExceptionイベントは、
catchされていない例外が発生し、
かつ DispatcherUnhandledException イベントでも処理されなかった場合に
発火するイベントです。
このイベントが発火した場合はアプリケーションの終了は決定事項です。
これはDispatcherUnhandledExceptionとの大きな違いです。
それ以上に大きな違いとして、
このイベントは本来WPFとは関係がありません。
使おうと思えばコンソールアプリケーションでも使うことができます。
(名前空間もSystem直下ですね)
このメソッド内で正常に終了するコードを書かなければ、
ユーザーの画面にはよくある「動作を停止しました」のダイアログが出てきます。
つまり、こういうことです。
- アプリケーションを終了させるコードを書く→アプリは終了する
- アプリケーションを終了させるコードを書かない →アプリは異常終了する
どうあってもアプリの終了は避けられません。
アプリの今際の際に発火するイベントということです。
UnhandledExceptionの詳しい使い方
さっそくサンプルコードを見てみましょう。
下の例では簡便化のためMainWindowのコードビハインドに記述していますが、
WPFであればApp.xaml.csのOnStartupなどでイベント購読するのが自然です。
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
AppDomain.CurrentDomain.UnhandledException += CurrentDomain_UnhandledException;
}
private void CurrentDomain_UnhandledException(object sender, UnhandledExceptionEventArgs e)
{
MessageBox.Show("申し訳ありません。\n" +
"お使いのアプリケーションは異常を検知したため終了します\n" +
"-- エラー内容 --\n" +
e.ExceptionObject.ToString(),
"異常終了");
Application.Current.Shutdown(1);
}
private void Button_Click(object sender, RoutedEventArgs e)
{
string a = null;
MessageBox.Show(a.ToString());
}
}
ボタンをクリックすると、
例外が発生したことをお知らせするダイアログが表示されます。
その後アプリケーションは終了します。
異常終了ではないので、標準のエラーダイアログが表示されないことがポイントです。
また、ExceptionObjectプロパティを取得することで、
実際に起きた例外の情報を出力することができます。
(プロパティはobject型なので、
詳細に取得したい場合はException型にキャストする必要があります。)
MessageプロパティとStackTraceプロパティを出力するだけであれば、
サンプルコードのようにToStringするだけでも充分です。
例外を握りつぶしてアプリを続行させることはできない
最初にも述べましたが、UnhandledExceptionイベントでは、
発生した例外を握りつぶしてアプリケーションの続行を図ることはできません。
根元から特定の例外を握りつぶすなどの処理を行いたい場合は、
DispatcherUnhandledException を用いましょう。
まとめ
まとめです。
- UnhandledExceptionは未処理の例外があった時に発生するイベント
- 例外の情報を出力したりユーザーにお知らせが可能
- 例外を握りつぶしてアプリを続行させることは不可能
ここまでお読みいただきありがとうございました。
コメント