WinForm捕獲全局異常(捕獲未處理的異常)

2021-12-29 dotNET跨平臺

背景

我們在做WinForm程序的時候,一般都是對異常進行處理,但是,我們要防止不小心出現未知異常,導致軟體崩潰。也可採集系統未知的異常信息,防止出現異常,也無法下手。於是就有了如這篇文章標題所述的一個簡單的需求。

代碼實現

1、處理未捕獲的異常

                              static void Application_ThreadException(object sender, System.Threading.ThreadExceptionEventArgs e) {
string str = ""; string strDateInfo = "出現應用程式未處理的異常:" + DateTime.Now.ToString() + "\r\n"; Exception error = e.Exception as Exception; if (error != null) { str = string.Format(strDateInfo + "異常類型:{0}\r\n異常消息:{1}\r\n異常信息:{2}\r\n", error.GetType().Name, error.Message, error.StackTrace); } else { str = string.Format("應用程式線程錯誤:{0}", e); } Helper.GetInstance().PlanLog(str, LogType.應用程式異常.ToString()); MessageBox.Show("發生致命錯誤,請及時聯繫作者!", "系統錯誤", MessageBoxButtons.OK, MessageBoxIcon.Error); }

2、處理UI線程異常

  static void CurrentDomain_UnhandledException(object sender, UnhandledExceptionEventArgs e) {      string str = "";      Exception error = e.ExceptionObject as Exception;      string strDateInfo = "出現應用程式未處理的異常:" + DateTime.Now.ToString() + "\r\n";      if (error != null) {        str = string.Format(strDateInfo + "Application UnhandledException:{0};\n\r堆棧信息:{1}", error.Message, error.StackTrace);      }      else {        str = string.Format("Application UnhandledError:{0}", e);      }      Helper.GetInstance().PlanLog(str, LogType.應用程式異常.ToString());                    MessageBox.Show("發生致命錯誤,請停止當前操作並及時聯繫作者!", "系統錯誤", MessageBoxButtons.OK, MessageBoxIcon.Error);    }

3、處理非UI線程異常

              [STAThread]    static void Main() {      try {                    Thread _UserMessageThread;                           _UserMessageThread = new Thread(new ThreadStart(LoginManager.GetInstance().test));        _UserMessageThread.IsBackground = true;        _UserMessageThread.Start();
Application.SetUnhandledExceptionMode(UnhandledExceptionMode.CatchException); Application.ThreadException += new System.Threading.ThreadExceptionEventHandler(Application_ThreadException); AppDomain.CurrentDomain.UnhandledException += new UnhandledExceptionEventHandler(CurrentDomain_UnhandledException); Application.EnableVisualStyles(); Application.SetCompatibleTextRenderingDefault(false); Xw.Common.Sys.SysConfig.AppExwcutePath = Application.ExecutablePath; Xw.Common.Sys.SysConfig.AppStartPath = Application.StartupPath; Xw.Common.Sys.SysConfig.Version = "V1.0.0"; Xw.Common.Sys.SysConfig.SoftFullName = "拍鞋網"; Xw.Common.Sys.SysConfig.SoftName = "軟體園店"; if (!Xw.Common.Sys.SysConfig.IsOnlyRunSoft("PaiXie.Pos.Client")) { Xw.Common.Sys.MsgBoxWin.ShowInformation("該程序已運行!"); return; } Application.Run(new Login()); } catch (Exception ex) { string str = ""; string strDateInfo = "出現應用程式未處理的異常:" + DateTime.Now.ToString() + "\r\n"; if (ex != null) { str = string.Format(strDateInfo + "異常類型:{0}\r\n異常消息:{1}\r\n異常信息:{2}\r\n", ex.GetType().Name, ex.Message, ex.StackTrace); } else { str = string.Format("應用程式線程錯誤:{0}", ex); } Helper.GetInstance().PlanLog(str, LogType.應用程式異常.ToString()); MessageBox.Show("發生致命錯誤,請及時聯繫作者!", "系統錯誤", MessageBoxButtons.OK, MessageBoxIcon.Error); } }

完整代碼
using PaiXie.Pos.Client.Core;using PaiXie.Utils;using System;using System.Collections.Generic;using System.Linq;using System.Threading;using System.Windows.Forms;namespace PaiXie.Pos.Client {  static class Program {                    [STAThread]    static void Main() {      try {                    Thread _UserMessageThread;                           _UserMessageThread = new Thread(new ThreadStart(LoginManager.GetInstance().test));        _UserMessageThread.IsBackground = true;        _UserMessageThread.Start();
Application.SetUnhandledExceptionMode(UnhandledExceptionMode.CatchException); Application.ThreadException += new System.Threading.ThreadExceptionEventHandler(Application_ThreadException); AppDomain.CurrentDomain.UnhandledException += new UnhandledExceptionEventHandler(CurrentDomain_UnhandledException); Application.EnableVisualStyles(); Application.SetCompatibleTextRenderingDefault(false); Xw.Common.Sys.SysConfig.AppExwcutePath = Application.ExecutablePath; Xw.Common.Sys.SysConfig.AppStartPath = Application.StartupPath; Xw.Common.Sys.SysConfig.Version = "V1.0.0"; Xw.Common.Sys.SysConfig.SoftFullName = "拍鞋網"; Xw.Common.Sys.SysConfig.SoftName = "軟體園店"; if (!Xw.Common.Sys.SysConfig.IsOnlyRunSoft("PaiXie.Pos.Client")) { Xw.Common.Sys.MsgBoxWin.ShowInformation("該程序已運行!"); return; } Application.Run(new Login()); } catch (Exception ex) { string str = ""; string strDateInfo = "出現應用程式未處理的異常:" + DateTime.Now.ToString() + "\r\n"; if (ex != null) { str = string.Format(strDateInfo + "異常類型:{0}\r\n異常消息:{1}\r\n異常信息:{2}\r\n", ex.GetType().Name, ex.Message, ex.StackTrace); } else { str = string.Format("應用程式線程錯誤:{0}", ex); } Helper.GetInstance().PlanLog(str, LogType.應用程式異常.ToString()); MessageBox.Show("發生致命錯誤,請及時聯繫作者!", "系統錯誤", MessageBoxButtons.OK, MessageBoxIcon.Error); } } static void Application_ThreadException(object sender, System.Threading.ThreadExceptionEventArgs e) {
string str = ""; string strDateInfo = "出現應用程式未處理的異常:" + DateTime.Now.ToString() + "\r\n"; Exception error = e.Exception as Exception; if (error != null) { str = string.Format(strDateInfo + "異常類型:{0}\r\n異常消息:{1}\r\n異常信息:{2}\r\n", error.GetType().Name, error.Message, error.StackTrace); } else { str = string.Format("應用程式線程錯誤:{0}", e); } Helper.GetInstance().PlanLog(str, LogType.應用程式異常.ToString()); MessageBox.Show("發生致命錯誤,請及時聯繫作者!", "系統錯誤", MessageBoxButtons.OK, MessageBoxIcon.Error); } static void CurrentDomain_UnhandledException(object sender, UnhandledExceptionEventArgs e) { string str = ""; Exception error = e.ExceptionObject as Exception; string strDateInfo = "出現應用程式未處理的異常:" + DateTime.Now.ToString() + "\r\n"; if (error != null) { str = string.Format(strDateInfo + "Application UnhandledException:{0};\n\r堆棧信息:{1}", error.Message, error.StackTrace); } else { str = string.Format("Application UnhandledError:{0}", e); } Helper.GetInstance().PlanLog(str, LogType.應用程式異常.ToString()); MessageBox.Show("發生致命錯誤,請停止當前操作並及時聯繫作者!", "系統錯誤", MessageBoxButtons.OK, MessageBoxIcon.Error); } }}

總結

針對異常,我們肯定無法事先全部預知,所以進行全局異常捕獲還是很有必要的。

相關焦點

  • Python異常捕獲與處理
    什麼是異常?異常即是一個事件,該事件會在程序執行過程中發生,影響了程序的正常執行。一般情況下,在Python無法正常處理程序時就會發生一個異常。異常是Python對象,表示一個錯誤。當Python腳本發生異常時我們需要捕獲處理它,否則程序會終止執行。當一個未捕獲的異常發生時,Python將結束程序並列印一個堆棧跟蹤信息,以及異常名和附加信息。
  • 基礎 | Java 中的異常捕獲及處理
    為了能夠及時有效地處理程序中的運行錯誤,Java 專門引入了異常類。Throwable 類是所有異常和錯誤的超類,下面有 Error 和 Exception 兩個子類分別表示錯誤和異常。我們不討論關於 Error 類型的異常處理,因為它們通常是災難性的致命錯誤,不是程序可以控制的。
  • python異常的捕獲與傳遞
    as errorMsg: print('產生錯誤了:%s'%errorMsg)else: print('沒有捕獲到異常,真高興')運行結果如下:<6> try...finally...,信息是:%s"%result) print("----test3-2----") test3() print("-華麗的分割線") test2()運行結果:總結:如果try嵌套,那麼如果裡面的try沒有捕獲到這個異常,那麼外面的try會接收到這個異常,然後進行處理,如果外邊的try依然沒有捕獲到,那麼再進行傳遞。。。
  • python中的異常捕獲
    ,比如除數為0的異常,可能初次測試時被除數都不為0,開發者就認為代碼是ok的,但是當處理的項目多了,某一天處理了一個除數為0的事務時,代碼報錯了,此時才意識到代碼存在bug, 這也是為什麼軟體開發不能一步到位,而是不斷迭代升級的原因,只有當代碼處理的項目足夠多的,範圍足夠廣,才能夠發現現有代碼的不足,從而做出改進。
  • php中try catch捕獲異常實例詳解
    具體方法分析如下:php中try catch可以幫助我們捕獲程序代碼的異常了,這樣我們可以很好的處理一些不必要的錯誤了,感興趣的朋友可以一起來看看。PHP中try{}catch{}語句概述PHP5添加了類似於其它語言的異常處理模塊。在 PHP 代碼中所產生的異常可被 throw語句拋出並被 catch 語句捕獲。
  • python學習筆記(9): try...except 異常捕獲
    當無法正確處理程序時就會出現異常。當異常發生時我們需要捕獲處理它,否則程序會終止執行。二、基礎語法捕捉異常可以使用tryexcept語句。如果你不想在異常發生時結束你的程序,只需在try裡捕獲它。try:    檢測異常代碼段except:    發生異常後執行代碼段else:    未發生異常執行代碼段finally:    最終執行代碼段三、基本原理
  • 前端異常捕獲上報
    但是,它可以捕獲到所有類型的錯誤嗎?比如:資源加載地址錯誤?window.addEventListener('error)資源地址錯誤怎麼捕獲?<img src="/xxx.png" /> window.addEventListener('error', (event) => { console.log('event err:', event) }, true) // 第三個參數為 true ,選擇捕獲的方式監聽複製代碼promise 怎麼捕獲
  • junit5如何斷言已經被捕獲異常?
    前置:外部方法無法捕獲內部方法中已經被catch的異常(屏蔽catch後又throw異常的場景)junit測試框架場景2是本文重點場景1:如果方法中throw一個異常,沒有catch:public static Integer convertToInt(String str) {
  • springboot之全局異常處理
    一、項目結構二、創建TestError類,捕獲controller的方法異常//controller輔助類,捕獲異常@ControllerAdvice(basePackages = "cn.bdqn.controller")public class TestError {//統一處理某一類異常,從而能夠減少代碼重複率和複雜度@ExceptionHandler(RuntimeException.class)
  • 同樣都是捕獲異常,為啥要不一樣吶?
    」以及如何「處理異常」,如果你對這方面現在還不了解,可以先看一下這兩篇文章:零基礎學習 Python 之錯誤 & 異常零基礎學習 Python 之處理異常後來因為某些原因,我發現在 Python2 和 Python3 中對於「捕獲異常」是有區別的,雖然我一直用的是 Python3,但是還是依然有一部分讀者用的是 Python2,所以我準備再用這一篇文章來寫一下不同版本的 Python 對於捕獲異常的差異,順便再補充一下捕獲多個不同的異常應該如何去做。
  • 如何優雅處理前端異常?
    對於前端來說,我們可做的異常捕獲還真不少。總結一下,大概如下:JS 語法錯誤、代碼異常AJAX 請求異常靜態資源加載異常Promise 異常Iframe 異常跨域 Script error崩潰和卡頓下面我會針對每種具體情況來說明如何處理這些異常。
  • 一種Vue應用程式錯誤/異常處理機制
    在應用程式中擁有良好的錯誤處理機制可以帶來很多的好處,如下:良好的錯誤處理機制可以避免應用程式在出現未處理的異常時崩潰在生產環境下,可以輕鬆地存儲或者跟蹤錯誤記錄日誌,以便異常的處理可以統一處理錯誤信息,例如在不破壞應用程式交互的情況下,更改錯誤信息展示UI在前端應用程式中,最常見的錯誤/異常類型可能包括以下幾種:有很多方法可以解決上面的問題,例如使用 eslint 來檢查語法錯誤,使用適當的 try-catch
  • 跟我學java編程—使用try和catch捕獲異常
    前面了解了Java異常和異常處理類,本節講述如何使用try和catch語句捕獲異常。Java程序在執行過程中如果出現異常,會自動生成一個異常對象,該異常對象將被自動提交給JVM,當JVM接收到異常對象時,會尋找能處理這一異常的代碼,並把當前異常對象交給其處理,這一過程稱為捕獲(catch)異常。如果JVM找不到可以捕獲異常的方法,則運行時系統將終止,相應的Java程序也將退出。
  • Promise 和 async/await 的異常處理,原來還有這種坑!
    答案是,此處的異常將無法捕獲到!當getList()拋出異常後,嗯,流程就失控了。Promise的異常捕獲方式打開控制臺會發現,上面的例子將會拋出 Uncaught (in promise)異常。這裡要提到Promise的異常處理流程。
  • JAVA異常及其異常處理方式
    常見的異常輸入輸出異常:IOException算術異常類:ArithmeticExecption空指針異常類:NullPointerException類型強制轉換異常:ClassCastException操作資料庫異常:SQLException文件未找到異常:FileNotFoundException數組負下標異常:NegativeArrayException數組下標越界異常
  • Spring Boot全局異常處理整理
    ,在日常web開發中發生了異常,往往是需要通過一個統一的異常處理來保證客戶端能夠收到友好的提示。/localhost:8080/spring/ex 的時候,就會被我們這個方法捕獲了。如果@ExceptionHandler所在的類帶有@ControllerAdvice註解,則此方法會作用在全局。該註解用於標註處理方法處理那些特定的異常。
  • 面試官:用一句話描述 JS 異常是否能被 try catch 捕獲到 ?
    面試者:能捕捉到的異常必須是線程執行已經進入 try catch 但 try catch 未執行完的時候拋出來的。我們我們來分析下這個一句話描述 try catch 的含義。主要分為三段:try catch 之前,之中,之後。
  • Java【8】異常處理
    異常處理機制——當程序出現錯誤後,程序如何處理。具體來說,異常機制提供了程序退出的安全通道。當出現錯誤後,程序執行的流程發生改變,程序的控制權轉移到異常處理器。★ 掌握和編寫異常處理機製程序:找到異常出現的邏輯、使用完整的數據測試、形成有針對性的異常處理。
  • Python 異常處理
    前言程序設計總是會報錯的,之前有談過幾次異常的處理,現在再來說一說:什麼是異常?當 Python 檢測到一個錯誤時,解釋器就無法繼續執行了,並且給出一個錯誤提示。比如寫入文件的時候,磁碟滿了,寫不進去了,或者從網絡抓取數據,網絡突然中斷。
  • python 異常處理
    當Python檢測到一個錯誤時,解釋器就無法繼續執行了,反而出現了一些錯誤的提示,這就是所謂的"異常"捕獲異常<1>捕獲異常 try...except...看如下示例:try: print('test--1---') open('123.txt','r') print('test--2---')except IOError: pass說明:此程序看不到任何錯誤,因為用except 捕獲到了IOError異常,並添加了處理的方法pass 表示實現了相應的實現,但什麼也不做;如果把pass