今際の際を捕捉するUnhandledException

C#
スポンサーリンク

アプリの終了間際に発生するイベント

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は未処理の例外があった時に発生するイベント
  • 例外の情報を出力したりユーザーにお知らせが可能
  • 例外を握りつぶしてアプリを続行させることは不可能

ここまでお読みいただきありがとうございました。

コメント

タイトルとURLをコピーしました