物理の駅 Physics station by 現役研究者

テクノロジーは共有されてこそ栄える

C# WPF アプリケーションで未処理例外に対応する方法

mseeeen.msen.jp

hilapon.hatenadiary.org

上の記事にある通り、 App.xaml.cs を以下のようにする。

using System;
using System.Diagnostics;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Threading;

namespace MyApplication
{
    /// <summary>
    /// App.xaml の相互作用ロジック
    /// </summary>
    public partial class App : Application
    {
        public App()
        {
            DispatcherUnhandledException += Application_DispatcherUnhandledException;
            TaskScheduler.UnobservedTaskException += TaskScheduler_UnobservedTaskException;
            AppDomain.CurrentDomain.UnhandledException += CurrentDomain_UnhandledException;
        }
        public void Application_DispatcherUnhandledException(object sender, DispatcherUnhandledExceptionEventArgs e)
        {
            e.Handled = true;
            var ex = e.Exception as Exception;
            var st = new StackTrace(ex, true);
            var frame = st.GetFrame(0);
            string message = string.Format("A system error in UI thread has occurred.\n" +
                "({0} {1})\n({2} line:{3})",
                ex.GetType(), ex.Message, frame.GetFileName(), frame.GetFileLineNumber());
            MessageBox.Show(message);
        }
        private void TaskScheduler_UnobservedTaskException(object sender, UnobservedTaskExceptionEventArgs e)
        {
            var ex = e.Exception.InnerException as Exception;
            var st = new StackTrace(ex, true);
            var frame = st.GetFrame(0);
            string message = string.Format("A system error in TaskScheduler has occurred.\n" +
                "Are you sure to continue?\n" +
                "({0} {1})\n({2} line:{3})",
                ex.GetType(), ex.Message, frame.GetFileName(), frame.GetFileLineNumber());
            if (MessageBox.Show(message, "", MessageBoxButton.YesNo) == MessageBoxResult.Yes)
            {
                e.SetObserved();
            }
            else { Environment.Exit(1); }
        }
        public void CurrentDomain_UnhandledException(object sender, UnhandledExceptionEventArgs e)
        {
            var ex = e.ExceptionObject as Exception;
            var st = new StackTrace(ex, true);
            var frame = st.GetFrame(0);
            string message = string.Format("A system error in AppDomain.CurrentDomain has occurred.\n" +
                "({0} {1})\n({2} line:{3})",
                ex.GetType(), ex.Message, frame.GetFileName(), frame.GetFileLineNumber());
            MessageBox.Show(message);
        }
    }
}