1. 程式人生 > >WPF 全域性異常處理

WPF 全域性異常處理

直接上程式碼:

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

namespace WpfApplication1
{
    /// <summary>
    /// App.xaml 的互動邏輯
    /// </summary>
    public partial class App : Application
    {
        private void Application_Startup(object sender, StartupEventArgs e)
        {
            Application.Current.StartupUri = new Uri("TestWindow.xaml",UriKind.Relative);

            //UI執行緒未捕獲異常處理事件(UI主執行緒)
            this.DispatcherUnhandledException += App_DispatcherUnhandledException;
            //非UI執行緒未捕獲異常處理事件(例如自己建立的一個子執行緒)
            AppDomain.CurrentDomain.UnhandledException += CurrentDomain_UnhandledException;
            //Task執行緒內未捕獲異常處理事件
            TaskScheduler.UnobservedTaskException += TaskScheduler_UnobservedTaskException;
        }

        //UI執行緒未捕獲異常處理事件(UI主執行緒)
        private void App_DispatcherUnhandledException(object sender, DispatcherUnhandledExceptionEventArgs e)
        {
            Exception ex = e.Exception;
            string msg = String.Format("{0}\n\n{1}", ex.Message, ex.StackTrace);//異常資訊 和 呼叫堆疊資訊
            MessageBox.Show(msg, "UI執行緒異常");

            e.Handled = true;//表示異常已處理,可以繼續執行
        }

        //非UI執行緒未捕獲異常處理事件(例如自己建立的一個子執行緒)
        //如果UI執行緒異常DispatcherUnhandledException未註冊,則如果發生了UI執行緒未處理異常也會觸發此異常事件
        //此機制的異常捕獲後應用程式會直接終止。沒有像DispatcherUnhandledException事件中的Handler=true的處理方式,可以通過比如Dispatcher.Invoke將子執行緒異常丟在UI主執行緒異常處理機制中處理
        private void CurrentDomain_UnhandledException(object sender, UnhandledExceptionEventArgs e)
        {
            Exception ex = e.ExceptionObject as Exception;
            if (ex != null)
            {
                string msg = String.Format("{0}\n\n{1}", ex.Message, ex.StackTrace);//異常資訊 和 呼叫堆疊資訊
                MessageBox.Show(msg, "非UI執行緒異常");
            }
        }

        //Task執行緒內未捕獲異常處理事件
        private void TaskScheduler_UnobservedTaskException(object sender, UnobservedTaskExceptionEventArgs e)
        {
            Exception ex = e.Exception;
            string msg = String.Format("{0}\n\n{1}", ex.Message, ex.StackTrace);
            MessageBox.Show(msg, "Task異常");
        }

        //異常處理 封裝
        private void OnExceptionHandler(Exception ex)
        {
            if(ex != null)
            {
                string errorMsg = "";
                if(ex.InnerException != null)
                {
                    errorMsg += String.Format("【InnerException】{0}\n{1}\n",ex.InnerException.Message,ex.InnerException.StackTrace);
                }
                errorMsg += String.Format("{0}\n{1}", ex.Message, ex.StackTrace);
                
                LogManager.ErrorLog(errorMsg);//自己封裝的日誌管理
            }
        }
    }
}