2013年10月09日

WPFサンプル:未処理例外に対応する

   このエントリーをはてなブックマークに追加 Clip to Evernote
アプリケーション実行中に例外が発生し、どこでもハンドルされなかった場合、アプリケーソンは異常終了してしまいます。僕が試した環境では、エラーダイアログも何もで出ずにプログラムが終わってしまいました。

WPFでは、ハンドルされない例外を検出するためのDispatcherUnhandledException イベントを利用することで、既定の動作を変更し、ユーザーにわかりやすい情報を表示させることが可能になります。

DispatcherUnhandledException イベントを利用するには、App.XAMLで、DispatcherUnhandledExceptionイベントハンドラを以下のように設定します。

<Application x:Class="UnhandledExceptionSample.App"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             StartupUri="MainWindow.xaml"
             DispatcherUnhandledException="Application_DispatcherUnhandledException">
    <Application.Resources>
        
    </Application.Resources>
</Application>

App.Xaml.csに、このイベントハンドラを記述します。

using System.Windows;
using System.Windows.Threading;
namespace UnhandledExceptionSample {
    public partial class App : Application {
        public void Application_DispatcherUnhandledException(object sender, DispatcherUnhandledExceptionEventArgs e) {
            string message = string.Format(
                "大変申し訳けありません。システムエラーが発生しました。\n ({0} {1})",
                e.Exception.GetType(), e.Exception.Message);
            MessageBox.Show(message);
            e.Handled = true;
        }
    }
}

DispatcherUnhandledExceptionイベントハンドラ―には、第2引数に、未処理の例外情報を含むDispatcherUnhandledExceptionEventArgsが渡されます。このクラスのプロパティ Exceptionを参照することで未処理の例外情報を得ることができます。

未処理の例外を処理した場合には、Handledプロパティにtrueを設定します。こうすることで、処理済みであることをApplicationオブジェクトに知らせ、既定の動作を抑制することができます。

今回は、DispatcherUnhandledException イベントの設定有無でどうアプリケーションの動作が変わるかを確認するため、MainWindow側のコードを以下のように記述しました。

<Window x:Class="UnhandledExceptionSample.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="MainWindow" Height="160" Width="225">
    <Grid>
        <Button Content="例外発生" HorizontalAlignment="Center"
                Margin="0,27,0,0" VerticalAlignment="Top" Width="105"
                Click="Button_Click_1"/>
        <Button Content="例外処理解除" HorizontalAlignment="Center"
                Margin="0,72,0,0" VerticalAlignment="Top" Width="105"
                Click="Button_Click_2"/>
    </Grid>
</Window>


using System.Windows;
namespace UnhandledExceptionSample {
    public partial class MainWindow : Window {
        public MainWindow() {
            InitializeComponent();
        }
        private void Button_Click_1(object sender, RoutedEventArgs e) {
            throw new System.NotImplementedException("まだ実装していません");
        }
        private void Button_Click_2(object sender, RoutedEventArgs e) {
            App app = Application.Current as App;
            app.DispatcherUnhandledException -= app.Application_DispatcherUnhandledException;
        }
    }
}

実行結果を示します。

[例外発生]ボタンを押したときの画面
ExceptionProc



WPFサンプル・目次


この記事へのコメント
UIスレッド以外もほしい?
Posted by karuakun at 2013年10月10日 10:57
AppDomain.CurrentDomain.UnhandledException については、気が向いたらアップします。
Posted by Gushwell at 2013年10月10日 21:32
 

この記事へのトラックバックURL

http://trackback.blogsys.jp/livedoor/gushwell/52335498