C#自訂異常處理(自訂例外)

來源:互聯網
上載者:User

http://www.cnblogs.com/winnerlan/archive/2008/05/24/1206644.html

對.NET類來說,一般的異常類 System.Exception
派生於 System.Object。還有許多定義好的異常類(如:System.SystemException、System.ApplicationException等),他們又派生於
System.Exception 類。其中System.ApplicationException
類是第三方定義的異常類,如果我們要自訂異常類,那麼就應派生於它。

    我們要站在異常一定可能會發生的角度來編寫例外處理常式,應對程式有可能發生的錯誤建立一個良好的異常處理策略。
    在做異常處理的時候,最好能在應用程式所有的入口處(事件處理函數,主函數,線程入口)使用try-catch。但是不要在程式建構函式入口處添加try-catch,因為此處產生異常,它自己並沒有能力來處理,因為它還沒有構造完畢,只能再向外層拋出異常。
    但我們也不能盲目使用異常。而且使用異常,可能會在一定程度上影響到程式的效能(C#中使用異常一般不影響效能)。

        // 自訂異常類
        public class MyException : ApplicationException
        {
            public MyException(string message) : base(message)
            {
            }

            public MyException(string message,Exception innerException)
                : base(message,innerException)
            {
            }
        }

    全域異常處理、多線程中的異常處理

將全域異常處理函數的委託加入到 Application.ThreadException
中,實現全域異常處理,但它只能處理主線程中未捕獲的異常。在多線程異常處理時,背景工作執行緒/輔線程中產生異常,可以把它轉給主線程來完成異常處理。如果線程之間不通知,是無法直接捕捉異常的。若沒有去處理背景工作執行緒/輔線程中產生的異常,該異常將會“消失”掉。

為什麼要把異常處理都交給主線程去做呢?舉個例子:在WinForm裡我們使用多線程來處理介面元素,一旦有異常發生就將異常訊息顯示出來。那麼,是直接在異常發生後就MessageBox,還是將訊息交給MainUI來統一顯示?試想一下,程式要是複雜點或是有多個介面採用多線程來顯示介面元素,那麼採用前者,我們就算知道了異常的詳細資料,但可能還是很難找到究竟是哪裡出了問題。而通過MainUI來顯示,情況就要好很多了,尤其是還設計到其他東西的時候(如:多語言環境)。當然,這個例子只是很小的一個方面。下面就來看怎麼來實現:

using System;
using System.Drawing;
using System.Collections;
using System.ComponentModel;
using System.Windows.Forms;
using System.Data;
using System.Threading;

namespace ThreadApp
{
    public class frmMain : System.Windows.Forms.Form
    {
        private System.Windows.Forms.Button btRun;
        /// 
        /// 必需的設計器變數。
        /// 
        private System.ComponentModel.Container components = null;
        
        public delegate void WorkerThreadExceptionHandlerDelegate(Exception e);
        void WorkerThreadExceptionHandler(Exception e)
        {
            this.Text = "Disposed.";
            MainUIThreadExceptionHandler(this, new System.Threading.ThreadExceptionEventArgs(e));
        }

        public frmMain()
        {
            InitializeComponent();
        }

        /// 
        /// 清理所有正在使用的資源。
        /// 
        protected override void Dispose( bool disposing )
        {
            if( disposing )
            {
                if (components != null) 
                {
                    components.Dispose();
                }
            }
            base.Dispose( disposing );
        }

        Windows 表單設計器產生的程式碼

        /// 
        /// 應用程式的主進入點。
        /// 
        [STAThread]
        static void Main() 
        {
            Application.ThreadException += new ThreadExceptionEventHandler(MainUIThreadExceptionHandler);
            Application.Run(new frmMain());
        }
        
        public static void MainUIThreadExceptionHandler(Exception e)
        {
            MainUIThreadExceptionHandler(null, new System.Threading.ThreadExceptionEventArgs(e));
        }

        public static void MainUIThreadExceptionHandler(object sender, ThreadExceptionEventArgs t)
        {
            MessageBox.Show(t.Exception.Message,"Exception",
                MessageBoxButtons.OK,
                MessageBoxIcon.Warning);    
        }


        private void ThrowException()
        {
            throw new NotImplementedException();
        }

        private void Run()
        {
            try
            {
                this.Text = "Waiting";  //[錯誤]這裡在2.0裡是編譯不通過的。因為它已經違背了我們的原則——不要跨線程操作(當前線程對介面線程的元素進行了操所)
                Thread.Sleep(2000);
                this.Text = "Throw Exception";
                ThrowException();
                this.Text = "Finished";  //[錯誤](同上)
            }
            catch(Exception e)
            {
                
              // 如果涉及到多線程的互操作時,
                // 可以運用BeginInvoke方法來實現多線程間的互訪問。
                this.BeginInvoke(
                    new WorkerThreadExceptionHandlerDelegate(
                    WorkerThreadExceptionHandler),
                    new object[]{e});            }
        }

        private void btRun_Click(object sender, System.EventArgs e)
        {
            ThreadStart ts = new ThreadStart(Run);
            Thread t = new Thread(ts);
            t.Start();

            //throw new NotSupportedException();
        }
    }
}

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.