C#中的異常處理機制

LG_985938339發表於2020-09-24

C#中的異常處理機制

  • 在C#中使用try catch finally語句來進行異常捕獲。一般而言,在有可能會發生錯誤的地方,我們便需要引入這個錯誤處理機制,避免程式的奔潰。
  • 首先介紹try,我們需要用try塊來包含將有可能會發生錯誤的程式碼,如果在try的程式碼塊中發生錯誤,那麼在發生錯誤的程式碼之後的try語句中的其他程式碼便不會再執行了,它會跳轉到catch或者finally中去。
  • 接下來是catch,catch就是用來捕獲程式碼中的錯誤的,一旦try塊中的程式碼發生錯誤,那麼catch就能捕獲這種型別的錯誤,而所有的錯誤都是繼承了Exception類的,所以在catch中指定引數型別為Exception的話,便能夠捕獲所有型別的錯誤。
  • 最後是finally,如果在這個程式中有無論是否發生錯誤,都一定需要被執行的程式碼,只要執行了try中的程式碼,那麼便可以把它寫在finally裡面。
  • try必須與catch或者finally其中一個或者兩個配對,否則就失去了try的意義了。
  • try塊的巢狀使用,在異常捕獲中,可以進行巢狀的使用。
        static void Main(string[] args)
        {
            try
            {
                try
                {
                    throw new Exception("發生了錯誤1");
                }
                catch (Exception e)
                {
                    throw e;
                }
            }
            catch (Exception e)
            {
                Console.WriteLine(e.Message);
            }
            Console.Read();
        }

我們可以在try中再次新增一個try catch語句,當發生錯誤時,優先觸發最內層的try語句,這時,我們也可以通過catch將該錯誤接著延續下來。

  • 我們需要注意的是,在使用了try catch語句時,請不要在catch語句不做任何的處理,即使不知道在這一步需要進行什麼處理,可以將該異常再次丟擲來或者記錄下來,否則當程式出現問題時,由於這裡將這個異常給遮蔽掉了而對程式的分析造成一定的困難。
  • 空try+finally的使用,在檢視ConcurrentQueue的原始碼的時候,發現了一個有意思的現象,
        internal bool TryAppend(T value)
        {
            if (m_high >= 31)
            {
                return false;
            }
            int num = 32;
            try
            {
            }
            finally
            {
                num = Interlocked.Increment(ref m_high);
                if (num <= 31)
                {
                    m_array[num] = value;
                    m_state[num].m_value = true;
                }
                if (num == 31)
                {
                    Grow();
                }
            }
            return num <= 31;
        }

併發佇列的新增元素的方法中竟然有一個空的try塊,既然try塊中為空,那麼還要它幹嘛呢,其實,醉翁之意不在酒,我們需要的是finally而已,因為finally不能單獨存在,所以必須要有一個try在這裡,那麼這個finally在這裡能保證什麼呢?答案就是,它能夠保證該執行緒在執行進入finally塊中時,即使執行緒呼叫abort引發了終止異常,依然能夠將finally程式碼執行完畢。

程式碼演示如下:

        static void Main(string[] args)
        {
            Thread th = new Thread(new ThreadStart(Method));
            th.Start();
            Thread.Sleep(1000);
            th.Abort();
            Console.Read();
        }
        static void Method()
        {
            Console.WriteLine("執行緒開始執行");
            Thread.Sleep(2000);
            Console.WriteLine("執行緒結束執行");
        }

在這裡插入圖片描述

在這裡可以看到,該執行緒在執行到1s時呼叫了abort終止了,輸出執行緒結束執行的語句並沒有被執行。

下面是使用了finally語句的程式

        static void Main(string[] args)
        {
            Thread th = new Thread(new ThreadStart(Method));
            th.Start();
            Thread.Sleep(1000);
            th.Abort();
            Console.Read();
        }
        static void Method()
        {
            Console.WriteLine("執行緒開始執行");
            try
            {
            }
            finally 
            {
                Thread.Sleep(2000);
                Console.WriteLine("執行緒結束執行");
            }
        }

在這裡插入圖片描述
同樣的,也是在該執行緒執行1s時引發了abort異常,但是,該執行緒依然能夠將finally語句執行完畢。

  • 所以說,當我們又需要在使用thread的情況下,保證一段程式碼的從開始執行到結束不會被打斷而結束掉,我們可以使用finally來防止abort引發的終止執行緒帶來的這個問題。

相關文章