五月天青色头像情侣网名,国产亚洲av片在线观看18女人,黑人巨茎大战俄罗斯美女,扒下她的小内裤打屁股

歡迎光臨散文網(wǎng) 會員登陸 & 注冊

.netcore全局異常處理

2023-03-01 18:25 作者:吳小敏63  | 我要投稿

一、背景

某天,應(yīng)用程序進程無緣無故退出,也就是我們通常說的崩潰。通常情況下,windows事件會記錄一條消息。但是有時候,我們發(fā)現(xiàn)這樣的信息,對于查找問題,還是遠遠不夠的,因為它說RunTime報錯。這時,我就想能不能自己捕獲全局未處理的異常。之所以有這樣的想法,因為之前在客戶端程序中寫過。這次我要在.netcore中處理,網(wǎng)上搜了一段代碼,高高興興地貼上去了,覺得上了保險箱。

二、探索

AppDomain.CurrentDomain.UnhandledException += CurrentDomain_UnhandledException; TaskScheduler.UnobservedTaskException += TaskScheduler_UnobservedTaskException;private static void TaskScheduler_UnobservedTaskException(object sender, UnobservedTaskExceptionEventArgs e) { ? ?foreach (var item ?in e.Exception.InnerExceptions) ? ?{ ? ? ?Logger.Error("未捕獲的Task異常 " + item.InnerException.Message + " ? ? " + item.GetType().Name); ? ?} }
private static void CurrentDomain_UnhandledException(object sender, UnhandledExceptionEventArgs e) { ? Exception exception = (Exception)e.ExceptionObject; ? Logger.Error("未捕獲的Domain異常 : " + exception.Message + "," + exception.StackTrace); ? Logger.Error("Runtime terminating: {0}", e.IsTerminating); }

給AppDomain和TaskScheduler注冊了兩個未處理異常的方法,等系統(tǒng)拋出異常時,可以捕獲。沒想到,程序一天之內(nèi)崩潰了兩次,比之前幾個月崩潰一次,頻率不知高了都少倍。下面是崩潰時的信息:

?

?

?這堆棧信息,得仔細看,才能看出門道,否則,可能會把重要的信息遺漏掉。猛的一看,程序哪里有未將對象引用到實例了?在業(yè)務(wù)代碼中苦苦思索,沒有找到。第二天早晨,仔細查看這個錯誤信息,發(fā)現(xiàn)這個異常竟然是TaskScheduler注冊的這個方法里面報出來的。于是我再次修改代碼:

?private static void TaskScheduler_UnobservedTaskException(object sender, UnobservedTaskExceptionEventArgs e) ?{ ? ?if (e.Exception?.InnerException != null) ? ?{ ? ? ? foreach (var item in e.Exception.InnerExceptions) ? ? ? { ? ? ? ? ?Logger.Error("未捕獲的Task異常 " + item.InnerException.Message + " ? ? " + item.GetType().Name); ? ? ? } ? ?} ? ?else ? ? { ? ? ? ? ?Logger.Error("[Exception]未捕獲的Task異常 " + e.Exception?.Message + " ? ? " + e.Exception?.StackTrace); ? ? } ? ? ?//將異常標識為已經(jīng)觀察到 ? ? ?e.SetObserved(); ?}

代碼是修改好了,在本地如何調(diào)試呢?網(wǎng)上說,GC回收Task的時候,會觸發(fā)Task里的異常,這個說法,應(yīng)該是正確的,請看上面的堆棧信息,回收的時候,會報異常發(fā)布出去。好,那我就人為制造一個異常:

Task.Run(() =>{ ? throw new Exception("測試異常"); }); Thread.Sleep(2000); GC.Collect();

可是代碼跑起來,沒有捕獲到任何異常。我以為GC沒有運行,我在網(wǎng)上搜索答案,類似這樣的寫法:

Task.Run(() =>{ ? throw new Exception("測試異常"); });while(true){ ?//不停地給數(shù)組分配內(nèi)存 ?//調(diào)用GC }

這次代碼運行起來,不僅異常沒有捕獲到,程序直接崩潰,說內(nèi)存不足,最后筆記本發(fā)燙,導致了藍屏。我不得不重啟電腦。

三、處理

網(wǎng)上一篇文章說,在Debug模式下,捕獲不到異常。Release下可以。于是,我切換了模式,果然可以。

Logger.Error("未捕獲的Task異常 " + item.InnerException.Message + " ? ? " + item.GetType().Name);

在處理全局異常的方法里,我記錄了日志,就這一句引發(fā)了未將對象引用到實例,調(diào)試發(fā)現(xiàn)? itm.InnerException為null,所以調(diào)用Message就異常了。下面,我們來處理:

private static void TaskScheduler_UnobservedTaskException(object sender, UnobservedTaskExceptionEventArgs e) {
? foreach (var item in e.Exception.InnerExceptions){ ? ? ?Logger.Error("未捕獲的Task異常 " + item.InnerException?.Message + " ? ? " + item.GetType().Name); ? }
}

處理好了,日志輸出:未捕獲的Task異常? ? Exception,從調(diào)試角度看,這樣的信息,就是個廢話,改改代碼:

private static void TaskScheduler_UnobservedTaskException(object sender, UnobservedTaskExceptionEventArgs e) { ? ?foreach (var item in e.Exception.InnerExceptions) ? ?{ ? ? ?Logger.Error("未捕獲的Task異常 " + item.Message + "," + item.StackTrace); ? ?} }

調(diào)試結(jié)果如下:

?

?這樣代碼就好了嗎?我擔心盡管處理好后,進程還會退出,網(wǎng)上搜了下,可以加入這句:

//將異常標識為已經(jīng)觀察到 e.SetObserved();

經(jīng)過調(diào)試,發(fā)現(xiàn)少了這句,也不會有問題,這句意思是不讓異常繼續(xù)往上冒泡,到此為止。這樣,程序就好了嗎?還是有所擔心,終極版的代碼:

private static void TaskScheduler_UnobservedTaskException(object sender, UnobservedTaskExceptionEventArgs e) { ? ?try ? ?{ ? ? ? ?foreach (var item in e.Exception.InnerExceptions) ? ? ? ?{ ? ? ? ? ? ?Logger.Error("未捕獲的Task異常 " + item.Message + "," + item.StackTrace); ? ? ? ?} ? ?} ? ?catch (Exception ex) ? ?{ ? ? ? ?Logger.Error($"TaskScheduler_UnobservedTaskException處理異常:{ex.Message}"); ? ?} ? ?//阻止異常冒泡 ? ?e.SetObserved(); }

這里之所以加上try..catch,因為擔心Logger出現(xiàn)異常,進程照樣會崩潰。所以,既想捕獲應(yīng)用程序中Task中的異常,又不想因此把程序整垮。

四、后記

網(wǎng)上的代碼,僅供參考和學習,要上服務(wù)器,還得經(jīng)過本地嚴格測試,誰知道會什么時候會引發(fā)災(zāi)難。


.netcore全局異常處理的評論 (共 條)

分享到微博請遵守國家法律
揭阳市| 彰武县| 清水河县| 江安县| 沙田区| 平泉县| 扎赉特旗| 阳城县| 枣强县| 体育| 庄河市| 阳泉市| 阿瓦提县| 疏勒县| 定结县| 平利县| 武鸣县| 射阳县| 申扎县| 雷波县| 平原县| 河津市| 盐边县| 灵璧县| 井冈山市| 登封市| 太原市| 巨野县| 柏乡县| 桂林市| 安宁市| 昌都县| 涡阳县| 漳州市| 石嘴山市| 桓台县| 鞍山市| 赫章县| 抚顺县| 乌审旗| 福建省|