前幾個星期在公司的測試服務器上搭建了 Exceptionless 對公司的 Asp.net core 項目進行遙測。在以前都是遠程桌面登陸上去,而後去翻日誌文件看有沒有異常,效率極其的低。用了 Exceptionless 以後,效率高了很多,並且能收集到更多信息了。git
最近準備要過年了,項目也上線了一段時間趨於穩定,算是比較閒了一點。想着要不把手上的 UWP 項目也加上 Exceptionless 進行遙測吧,畢竟微軟商店的 Dashboard 那異常也幾乎是看不出啥的,並且這測試服務器性能又是過剩的,不用白不用。github
但我一操做起來,就發現了個大問題,Exceptionless 官方並無提供 UWP 的庫(Winform、WPF、asp.net core 的都有)。翻查了 github 上相關的 issue,官方建議是用 .net standard 版本的。然而實際操做以後,我發現還須要額外的代碼來處理 UWP 中的 UnhandledException,本文就記錄一下。服務器
首先固然是在 Exceptionless 平臺上建立項目獲取 ApiKey 了,這個就很少說了。而後 UWP 項目引用 Exceptionless 的 nuget 包。asp.net
在 App.xaml.cs 的構造函數中添加 SetUpExceptionless 代碼:less
public App() { this.InitializeComponent(); this.Suspending += OnSuspending; SetUpExceptionless(); }
而後先初步實現 SetUpExceptionless 方法:函數
private void SetUpExceptionless() { var client = ExceptionlessClient.Default; client.Configuration.ServerUrl = ""; client.Configuration.ApiKey = ""; client.Startup(); }
因爲是自建 Exceptionless 平臺,因此須要配置一下 ServerUrl。ApiKey 配置爲從平臺獲取到的 ApiKey。性能
接下來是處理 UnhandledException,在 UWP 平臺中,有兩種狀況,一種是在 App 類上觸發的,另外一種是在 AppDomain 上觸發的。這兩種咱們都要監聽到。但如何監聽呢,這裏先看看官方在 WPF 平臺是如何實現的:測試
主要是圖上紅框的兩行,第一行主要是捕獲線程的異常,第二行捕獲了 App 的異常。而捕獲線程異常的方法內部用到了 Winform 的類,這裏咱們就忽略,由於 UWP 裏沒有這些類,並且 UWP 中非 UI 線程的異常是能夠經過 AppDomain.UnhandledException 事件來捕獲的。這裏咱們看第二行的實現:this
可見是對 System.Windows.Application.Current.DispatcherUnhandledException 事件進行了訂閱,而後給 Exceptionless。spa
依樣畫葫蘆,完善咱們的 SetUpExceptionless 方法:
private void SetUpExceptionless() { var client = ExceptionlessClient.Default; client.Configuration.ServerUrl = ""; client.Configuration.ApiKey = ""; UnhandledException += (sender, args) => { var contextData = new ContextData(); contextData.MarkAsUnhandledError(); contextData.SetSubmissionMethod("App_UnhandledException"); args.Exception.ToExceptionless(contextData, ExceptionlessClient.Default).Submit(); client.ProcessQueue(); }; AppDomain.CurrentDomain.UnhandledException += (sender, args) => { var exception = args.ExceptionObject as Exception; if (exception == null) { return; } var contextData = new ContextData(); contextData.MarkAsUnhandledError(); contextData.SetSubmissionMethod("AppDomain_UnhandledException"); exception.ToExceptionless(contextData, ExceptionlessClient.Default).Submit(); client.ProcessQueue(); }; client.Startup(); }
接下來咱們測試一下是否起效,先手動拋個異常,我就直接建一個 Button,而後 Click 拋個異常好了。
private void TestButton_Click(object sender, RoutedEventArgs e) { throw new Exception("測試 Exceptionless 集成"); }
運行後,點擊按鈕,而後 App 炸掉以後咱們去看 Exceptionless 平臺。
完美!