1. 程式人生 > >捕獲程序未拋出的異常

捕獲程序未拋出的異常

tar 運行 不能 catch 斷點 span 遇到 appdomain 測試

 

  這段時間,Unity項目遇到問題,工程中有很多有問題的代碼,調試的時候,這些代碼理應拋出異常但是卻沒有,這是一個很恐怖的事情,因為你根本不知道你代碼中有哪些不對,程序運行下來,就會遇到各種邏輯問題,查無對策。後來我研究了下,記錄了下來

  在unity中,子線程下的異常,如果不加try catch,可能不會被unity正常捕獲,故而你會不知道這裏有異常 

  先舉個栗子

    Thread t1,t2;
    List<int> list = null;
    void Start ()
    {
        
        try
        {

            t1 = new Thread(new ThreadStart(MyTest));
            t1.Start();
        }
        catch
        {
           
        }
               
    }

    void MyTest()
    {
        //輸出異常 1
        list.Add(1);
        try
        {
            list.Add(1);
        }
       catch(Exception e)
       {
            //輸出異常 2
            Debug.Log(e.ToString());
       }
       
    }

  這段代碼對一個null的引用嘗試讀寫,將會引發空引用異常。在我們調用start方法後,控制臺理應在執行“輸出異常1”和“輸出異常2”的時候打印異常信息,但是事實上,unity控制臺中什麽信息都沒打印。如果你把程序發布,後果是可想而知的。

  然後我嘗試在"輸出異常1"處加了斷點

技術分享圖片

  程序執行到這裏,調試程序直接“崩了”,所以這行的異常信息沒有輸出到控制臺,程序也沒有往下執行,下面的異常信息自然也不會輸出到控制臺。

  所以我猜測肯定是40行代碼導致t1子線程出了問題,所以unity不能正常捕獲這裏的異常或者輸出這裏的異常信息.

  那麽有沒有什麽辦法讓unity向我們報告這個異常信息呢?

  

    Thread t1;
    List<int> list = null;
    void Start ()
    {
AppDomain app = AppDomain.CurrentDomain; app.UnhandledException += App1_UnhandledException;
try { t1 = new Thread(new ThreadStart(MyTest)); t1.Start(); } catch { } } private void App1_UnhandledException(object sender, UnhandledExceptionEventArgs e) { Debug.Log(e.ExceptionObject.ToString()); }
void MyTest() { //輸出異常 1 list.Add(1); try { list.Add(1); } catch(Exception e) { //輸出異常 2 Debug.Log(e.ToString()); } }

  

  紅色部分是我新添加的代碼,測試運行,得到輸出

System.NullReferenceException: Object reference not set to an instance of an object
  at Test.MyTest () [0x00008] in E:\Demo\New Unity Project 3\Assets\Test.cs:40 
UnityEngine.Debug:Log(Object)
Test:App1_UnhandledException(Object, UnhandledExceptionEventArgs) (at Assets/Test.cs:33)

  我成功的打印出了異常,並獲得了異常位置(Test.cs:33)。

  

  AppDomain 描述一個運用程序域,當程序某個異常沒有被捕獲的時候,UnhandledException事件就會調用。下面是這個API詳細介紹.


  https://msdn.microsoft.com/zh-cn/library/system.appdomain.unhandledexception(v=vs.110).aspx

 

捕獲程序未拋出的異常