Q103. WPF で未処理例外に対応するには?

A.DispatcherUnhandledException イベントを使用します。

以下サンプルです。未処理例外情報をイベントログに保存します。
なお DispatcherUnhandledException イベントだけだとUIスレッドの未処理例外しか捕捉できません。UIスレッド以外の未処理例外も捕捉できるよう 以下のように AppDomain.UnhandledException イベントも実装するといいでしょう。

// C#
using System;
using System.Diagnostics;
using System.Windows;
using System.Windows.Threading;

namespace WpfApplication1
{
    public partial class App : Application {
        /// <summary>
        /// アプリケーション開始時のイベントハンドラ
        /// </summary>
        private void Application_Startup(object sender, StartupEventArgs e) {
            this.DispatcherUnhandledException += Application_DispatcherUnhandledException;
            AppDomain.CurrentDomain.UnhandledException += CurrentDomain_UnhandledException;
        }

        /// <summary>
        /// アプリケーション終了時のイベントハンドラ
        /// </summary>
        private void Application_Exit(object sender, ExitEventArgs e) {
            this.DispatcherUnhandledException -= Application_DispatcherUnhandledException;
            AppDomain.CurrentDomain.UnhandledException -= CurrentDomain_UnhandledException;
        }

        /// <summary>
        /// WPF UIスレッドでの未処理例外スロー時のイベントハンドラ
        /// </summary>
        private void Application_DispatcherUnhandledException(
            object sender, DispatcherUnhandledExceptionEventArgs e)
        {
            e.Handled = true;
            this.ReportUnhandledException(e.Exception);
        }

        /// <summary>
        /// UIスレッド以外の未処理例外スロー時のイベントハンドラ
        /// </summary>
        private void CurrentDomain_UnhandledException(
            object sender, UnhandledExceptionEventArgs e)
        {
            this.ReportUnhandledException(e.ExceptionObject as Exception);
        }

        /// <summary>
        /// 未処理例外をイベントログに出力します。
        /// </summary>
        private void ReportUnhandledException(Exception ex) {
            EventLog.WriteEntry(
                "サンプルアプリケーション", ex.ToString(), EventLogEntryType.Error);
            this.Shutdown();
        }
    }
}
' VB.NET
Option Explicit On
Option Strict On

Imports System
Imports System.Diagnostics
Imports System.Windows
Imports System.Windows.Threading

Public Class Application
    ''' <summary>
    ''' アプリケーション開始時のイベントハンドラ
    ''' </summary>
    Private Sub Application_Startup(sender As Object, e As StartupEventArgs) Handles Me.Startup
        ' 未処理例外を処理するイベントハンドラを登録
        AddHandler Me.DispatcherUnhandledException, AddressOf Application_DispatcherUnhandledException
        AddHandler AppDomain.CurrentDomain.UnhandledException, AddressOf CurrentDomain_UnhandledException
    End Sub

    ''' <summary>
    ''' アプリケーション終了時のイベントハンドラ
    ''' </summary>
    Private Sub Application_Exit(sender As Object, e As ExitEventArgs) Handles Me.Exit
        ' 未処理例外を処理するイベントハンドラを解除
        RemoveHandler Me.DispatcherUnhandledException, AddressOf Application_DispatcherUnhandledException
        RemoveHandler AppDomain.CurrentDomain.UnhandledException, AddressOf CurrentDomain_UnhandledException
    End Sub

    ''' <summary>
    ''' WPF UIスレッドでの未処理例外スロー時のイベントハンドラ
    ''' </summary>
    Private Sub Application_DispatcherUnhandledException(sender As Object, e As DispatcherUnhandledExceptionEventArgs)
        e.Handled = True
        Me.ReportUnhandledException(e.Exception)
    End Sub

    ''' <summary>
    ''' UIスレッド以外の未処理例外スロー時のイベントハンドラ
    ''' </summary>
    Private Sub CurrentDomain_UnhandledException(sender As Object, e As UnhandledExceptionEventArgs)
        Me.ReportUnhandledException(TryCast(e.ExceptionObject, Exception))
    End Sub

    ''' <summary>
    ''' 未処理例外をイベントログに出力します。
    ''' </summary>
    Private Sub ReportUnhandledException(ex As Exception)
        ' 例外情報をイベントログに出力
        EventLog.WriteEntry("サンプルアプリケーション", ex.ToString(), EventLogEntryType.Error)
        ' アプリケーションを終了
        Me.Shutdown()
    End Sub
End Class


C#クックブック 第3版

C#クックブック 第3版



WPF FAQ の目次に戻る