利用委托机制处理.NET中的异常

  • Post author:
  • Post category:其他



利用委托机制处理


.NET


中的异常


<?xml:namespace prefix = o ns = “urn:schemas-microsoft-com:office:office” />


Terrylee





2005





12





10







概述











.NET


中,可以轻松的通过


try-catch


块来捕获异常。为了防止在应用程序中出现未处理的异常,可以通过添加一个全局的异常处理函数,如果是多线程的处理,还必须考虑除了主线程之外的工作线程中的异常处理办法,这里用委托机制来实现。




主线程的异常处理








使用


Application


对象中的


ThreadException


属性设置一个


delegate


来捕获所有的未处理的主线程中出现的异常。注意这个全局异常处理程序,只能捕获到主线程中的异常,对于我们自己添加的工作线程、辅助线程的异常是捕获不到的。



在应用程序入口添加全局异常处理:




1

ExpandedBlockStart.gif
ContractedBlock.gif

/**/



///




<summary>





2


InBlock.gif


///


应用程序的主入口点。



3


ExpandedBlockEnd.gif


///




</summary>






4

None.gif

[STAThread]



5


None.gif


static




void


Main()



6


ExpandedBlockStart.gif
ContractedBlock.gif


dot.gif



{



7


ExpandedSubBlockStart.gif
ContractedSubBlock.gif


/**/



///


添加主线程的全局异常处理






8

InBlock.gif

Application.ThreadException


+=




new





9


InBlock.gif
ThreadExceptionEventHandler(



10


InBlock.gif
MainUIThreadExceptionHandler);



11


InBlock.gif



12


InBlock.gif
Application.Run(


new


Form1());



13


ExpandedBlockEnd.gif
}


处理程序:


1

None.gif

public




static




void


MainUIThreadExceptionHandler(Exception ex)



2


ExpandedBlockStart.gif
ContractedBlock.gif


dot.gif



{




3


InBlock.gif
MainUIThreadExceptionHandler(


null


,


new





4


InBlock.gif
ThreadExceptionEventArgs(ex));



5


ExpandedBlockEnd.gif
}






6


None.gif



7


ExpandedBlockStart.gif
ContractedBlock.gif


/**/



///




<summary>





8


InBlock.gif


///


主线程全局异常信息的处理



9


InBlock.gif


///




</summary>





10


InBlock.gif


///




<param name=”sender”></param>





11


ExpandedBlockEnd.gif


///




<param name=”t”></param>






12

None.gif

public




static




void


MainUIThreadExceptionHandler(


object





13


None.gif
sender, ThreadExceptionEventArgs e)



14


ExpandedBlockStart.gif
ContractedBlock.gif


dot.gif



{




15


InBlock.gif
MessageBox.Show(



16


InBlock.gif





应用程序发生了如下的异常信息








17


InBlock.gif


+















+


(


char


)


13





18


InBlock.gif


+


(


char


)


13




+


e.Exception.Message



19


InBlock.gif


+


(


char


)


13




+


(


char


)


13





20


InBlock.gif


+







请于系统管理员取得联系!








21


InBlock.gif


+


(


char


)


13




+


(


char


)


13





22


InBlock.gif
,





异常信息








23


InBlock.gif
, MessageBoxButtons.OK



24


InBlock.gif
, MessageBoxIcon.Error



25


InBlock.gif
, MessageBoxDefaultButton.Button1



26


InBlock.gif
, MessageBoxOptions.ServiceNotification);



27


ExpandedBlockEnd.gif
}






工作线程的异常处理








编写多线程代码时,我们必须考虑在工作线程中出现的异常。在线程的入口使用


try-catch


块,并通过


delegate


将发生的异常通知给主线程。必须将异常信息通知主线程,否则应用程序不会报错,异常将会消失。


在线程入口使用


try-catch


块:




1

ExpandedBlockStart.gif
ContractedBlock.gif

/**/



///




<summary>





2


InBlock.gif


///


在线程的入口点加入try-catch块



3


ExpandedBlockEnd.gif


///




</summary>






4

None.gif

private




void


DataSave()



5


ExpandedBlockStart.gif
ContractedBlock.gif


dot.gif



{




6


InBlock.gif


try





7


ExpandedSubBlockStart.gif
ContractedSubBlock.gif


dot.gif



{




8


InBlock.gif
CreateException();



9


ExpandedSubBlockEnd.gif
}






10


InBlock.gif


catch


(Exception e)



11


ExpandedSubBlockStart.gif
ContractedSubBlock.gif


dot.gif



{




12


ExpandedSubBlockStart.gif
ContractedSubBlock.gif


/**/



///


通过delegate转向工作线程的异常处理






13

InBlock.gif



new


WorkerThreadExceptionHandlerDelegate(



14


InBlock.gif
WorkerThreadExceptionHandler).BeginInvoke(e



15


InBlock.gif
,


null





16


InBlock.gif
,


null


);



17


ExpandedSubBlockEnd.gif
}






18


ExpandedBlockEnd.gif
}


工作线程异常的处理:




1

ExpandedBlockStart.gif
ContractedBlock.gif

/**/



///




<summary>





2


InBlock.gif


///


声明工作线程的delegate



3


ExpandedBlockEnd.gif


///




</summary>






4

None.gif

public




delegate




void





5


None.gif
WorkerThreadExceptionHandlerDelegate(Exception e);



6


None.gif



7


ExpandedBlockStart.gif
ContractedBlock.gif


/**/



///




<summary>





8


InBlock.gif


///


工作线程的异常处理



9


InBlock.gif


///




</summary>





10


ExpandedBlockEnd.gif


///




<param name=”e”></param>






11

None.gif

public




void


WorkerThreadExceptionHandler(Exception e)



12


ExpandedBlockStart.gif
ContractedBlock.gif


dot.gif



{




13


ExpandedSubBlockStart.gif
ContractedSubBlock.gif


/**/



///


添加其他的处理代码



14


InBlock.gif



15


ExpandedSubBlockEnd.gif


///


通知全局异常处理程序






16

InBlock.gif

MainUIThreadExceptionHandler(



17


InBlock.gif


this


,


new


System.Threading.



18


InBlock.gif
ThreadExceptionEventArgs(e));



19


ExpandedBlockEnd.gif
}



总结








对于捕获到异常,我们可以


Log


到文件或者数据库,但是必须保证捕获到所有的异常,以上通过委托机制实现了


.NET


中的主线程以及工作线程中的异常捕获。




完整的程序代码:




1

None.gif

using


System;



2


None.gif


using


System.Drawing;



3


None.gif


using


System.Collections;



4


None.gif


using


System.ComponentModel;



5


None.gif


using


System.Windows.Forms;



6


None.gif


using


System.Data;



7


None.gif


using


System.Threading;



8


None.gif



9


None.gif


namespace


UseDelegateException



10


ExpandedBlockStart.gif
ContractedBlock.gif


dot.gif



{




11


ExpandedSubBlockStart.gif
ContractedSubBlock.gif


/**/



///




<summary>





12


InBlock.gif


///


功能:利用Delegate实现异常的全局处理



13


InBlock.gif


///


编写:Terrylee



14


InBlock.gif


///


日期:2005年12月10日



15


ExpandedSubBlockEnd.gif


///




</summary>






16

InBlock.gif



public




class


Form1 : System.Windows.Forms.Form



17


ExpandedSubBlockStart.gif
ContractedSubBlock.gif


dot.gif



{




18


InBlock.gif


private


System.Windows.Forms.Button btnMainUIThread;



19


InBlock.gif


private


System.Windows.Forms.Button btnWorkThread;



20


ExpandedSubBlockStart.gif
ContractedSubBlock.gif


/**/



///




<summary>





21


InBlock.gif


///


必需的设计器变量。



22


ExpandedSubBlockEnd.gif


///




</summary>






23

InBlock.gif



private


System.ComponentModel.Container components


=




null


;



24


InBlock.gif



25


InBlock.gif


public


Form1()



26


ExpandedSubBlockStart.gif
ContractedSubBlock.gif


dot.gif



{




27


InBlock.gif


//





28


InBlock.gif


//


Windows 窗体设计器支持所必需的



29


InBlock.gif


//



30


InBlock.gif


InitializeComponent();



31


InBlock.gif



32


InBlock.gif


//





33


InBlock.gif


//


TODO: 在 InitializeComponent 调用后添加任何构造函数代码



34


InBlock.gif


//



35


ExpandedSubBlockEnd.gif


}






36


InBlock.gif



37


ExpandedSubBlockStart.gif
ContractedSubBlock.gif


/**/



///




<summary>





38


InBlock.gif


///


清理所有正在使用的资源。



39


ExpandedSubBlockEnd.gif


///




</summary>






40

InBlock.gif



protected




override




void


Dispose(


bool


disposing )



41


ExpandedSubBlockStart.gif
ContractedSubBlock.gif


dot.gif



{




42


InBlock.gif


if


( disposing )



43


ExpandedSubBlockStart.gif
ContractedSubBlock.gif


dot.gif



{




44


InBlock.gif


if


(components


!=




null


)



45


ExpandedSubBlockStart.gif
ContractedSubBlock.gif


dot.gif



{




46


InBlock.gif
components.Dispose();



47


ExpandedSubBlockEnd.gif
}






48


ExpandedSubBlockEnd.gif
}






49


InBlock.gif


base


.Dispose( disposing );



50


ExpandedSubBlockEnd.gif
}






51


InBlock.gif



52


ContractedSubBlock.gif
ExpandedSubBlockStart.gif


Windows 窗体设计器生成的代码



#region


Windows 窗体设计器生成的代码





53


ExpandedSubBlockStart.gif
ContractedSubBlock.gif


/**/



///




<summary>





54


InBlock.gif


///


设计器支持所需的方法 – 不要使用代码编辑器修改



55


InBlock.gif


///


此方法的内容。



56


ExpandedSubBlockEnd.gif


///




</summary>






57

InBlock.gif



private




void


InitializeComponent()



58


ExpandedSubBlockStart.gif
ContractedSubBlock.gif


dot.gif



{




59


InBlock.gif


this


.btnMainUIThread


=




new


System.Windows.Forms.Button();



60


InBlock.gif


this


.btnWorkThread


=




new


System.Windows.Forms.Button();



61


InBlock.gif


this


.SuspendLayout();



62


InBlock.gif


//





63


InBlock.gif


//


btnMainUIThread



64


InBlock.gif


//







65


InBlock.gif




this


.btnMainUIThread.Location


=




new


System.Drawing.Point(


40


,


72


);



66


InBlock.gif


this


.btnMainUIThread.Name


=







btnMainUIThread





;



67


InBlock.gif


this


.btnMainUIThread.Size


=




new


System.Drawing.Size(


112


,


48


);



68


InBlock.gif


this


.btnMainUIThread.TabIndex


=




0


;



69


InBlock.gif


this


.btnMainUIThread.Text


=







主线程异常





;



70


InBlock.gif


this


.btnMainUIThread.Click


+=




new


System.EventHandler(


this


.btnMainUIThread_Click);



71


InBlock.gif


//





72


InBlock.gif


//


btnWorkThread



73


InBlock.gif


//







74


InBlock.gif




this


.btnWorkThread.Location


=




new


System.Drawing.Point(


240


,


72


);



75


InBlock.gif


this


.btnWorkThread.Name


=







btnWorkThread





;



76


InBlock.gif


this


.btnWorkThread.Size


=




new


System.Drawing.Size(


112


,


48


);



77


InBlock.gif


this


.btnWorkThread.TabIndex


=




1


;



78


InBlock.gif


this


.btnWorkThread.Text


=







工作线程异常





;



79


InBlock.gif


this


.btnWorkThread.Click


+=




new


System.EventHandler(


this


.btnWorkThread_Click);



80


InBlock.gif


//





81


InBlock.gif


//


Form1



82


InBlock.gif


//







83


InBlock.gif




this


.AutoScaleBaseSize


=




new


System.Drawing.Size(


6


,


14


);



84


InBlock.gif


this


.ClientSize


=




new


System.Drawing.Size(


392


,


197


);



85


InBlock.gif


this


.Controls.Add(


this


.btnWorkThread);



86


InBlock.gif


this


.Controls.Add(


this


.btnMainUIThread);



87


InBlock.gif


this


.MaximizeBox


=




false


;



88


InBlock.gif


this


.Name


=







Form1





;



89


InBlock.gif


this


.Text


=







Form1





;



90


InBlock.gif


this


.ResumeLayout(


false


);



91


InBlock.gif



92


ExpandedSubBlockEnd.gif
}






93


ExpandedSubBlockEnd.gif


#endregion






94


InBlock.gif



95


ExpandedSubBlockStart.gif
ContractedSubBlock.gif


/**/



///




<summary>





96


InBlock.gif


///


应用程序的主入口点。



97


ExpandedSubBlockEnd.gif


///




</summary>






98

InBlock.gif

[STAThread]



99


InBlock.gif


static




void


Main()



100


ExpandedSubBlockStart.gif
ContractedSubBlock.gif


dot.gif



{



101


ExpandedSubBlockStart.gif
ContractedSubBlock.gif


/**/



///


添加主线程的全局异常处理






102

InBlock.gif

Application.ThreadException


+=




new





103


InBlock.gif
ThreadExceptionEventHandler(



104


InBlock.gif
MainUIThreadExceptionHandler);



105


InBlock.gif



106


InBlock.gif
Application.Run(


new


Form1());



107


ExpandedSubBlockEnd.gif
}






108


InBlock.gif



109


InBlock.gif


public




static




void


MainUIThreadExceptionHandler(Exception ex)



110


ExpandedSubBlockStart.gif
ContractedSubBlock.gif


dot.gif



{




111


InBlock.gif
MainUIThreadExceptionHandler(


null


,


new





112


InBlock.gif
ThreadExceptionEventArgs(ex));



113


ExpandedSubBlockEnd.gif
}






114


InBlock.gif



115


ExpandedSubBlockStart.gif
ContractedSubBlock.gif


/**/



///




<summary>





116


InBlock.gif


///


主线程全局异常信息的处理



117


InBlock.gif


///




</summary>





118


InBlock.gif


///




<param name=”sender”></param>





119


ExpandedSubBlockEnd.gif


///




<param name=”t”></param>






120

InBlock.gif



public




static




void


MainUIThreadExceptionHandler(


object





121


InBlock.gif
sender, ThreadExceptionEventArgs e)



122


ExpandedSubBlockStart.gif
ContractedSubBlock.gif


dot.gif



{




123


InBlock.gif
MessageBox.Show(



124


InBlock.gif





应用程序发生了如下的异常信息








125


InBlock.gif


+















+


(


char


)


13





126


InBlock.gif


+


(


char


)


13




+


e.Exception.Message



127


InBlock.gif


+


(


char


)


13




+


(


char


)


13





128


InBlock.gif


+







请于系统管理员取得联系!








129


InBlock.gif


+


(


char


)


13




+


(


char


)


13





130


InBlock.gif
,





异常信息








131


InBlock.gif
, MessageBoxButtons.OK



132


InBlock.gif
, MessageBoxIcon.Error



133


InBlock.gif
, MessageBoxDefaultButton.Button1



134


InBlock.gif
, MessageBoxOptions.ServiceNotification);



135


ExpandedSubBlockEnd.gif
}






136


InBlock.gif



137


ExpandedSubBlockStart.gif
ContractedSubBlock.gif


/**/



///




<summary>





138


InBlock.gif


///


声明工作线程的delegate



139


ExpandedSubBlockEnd.gif


///




</summary>






140

InBlock.gif



public




delegate




void





141


InBlock.gif
WorkerThreadExceptionHandlerDelegate(Exception e);



142


InBlock.gif



143


ExpandedSubBlockStart.gif
ContractedSubBlock.gif


/**/



///




<summary>





144


InBlock.gif


///


工作线程的异常处理



145


InBlock.gif


///




</summary>





146


ExpandedSubBlockEnd.gif


///




<param name=”e”></param>






147

InBlock.gif



public




void


WorkerThreadExceptionHandler(Exception e)



148


ExpandedSubBlockStart.gif
ContractedSubBlock.gif


dot.gif



{




149


ExpandedSubBlockStart.gif
ContractedSubBlock.gif


/**/



///


添加其他的处理代码



150


InBlock.gif



151


ExpandedSubBlockEnd.gif


///


通知全局异常处理程序






152

InBlock.gif

MainUIThreadExceptionHandler(



153


InBlock.gif


this


,


new


System.Threading.



154


InBlock.gif
ThreadExceptionEventArgs(e));



155


ExpandedSubBlockEnd.gif
}






156


ExpandedSubBlockStart.gif
ContractedSubBlock.gif


/**/



///




<summary>





157


InBlock.gif


///


制造异常信息,这里抛出一个除0的异常



158


ExpandedSubBlockEnd.gif


///




</summary>






159

InBlock.gif



private




void


CreateException()



160


ExpandedSubBlockStart.gif
ContractedSubBlock.gif


dot.gif



{




161


InBlock.gif


int


a


=




1


;



162


InBlock.gif


int


b


=




0


;



163


InBlock.gif



164


InBlock.gif


int


c;



165


InBlock.gif
c


=


a


/


b;



166


ExpandedSubBlockEnd.gif
}






167


InBlock.gif



168


ExpandedSubBlockStart.gif
ContractedSubBlock.gif


/**/



///




<summary>





169


InBlock.gif


///


在线程的入口点加入try-catch块



170


ExpandedSubBlockEnd.gif


///




</summary>






171

InBlock.gif



private




void


DataSave()



172


ExpandedSubBlockStart.gif
ContractedSubBlock.gif


dot.gif



{




173


InBlock.gif


try





174


ExpandedSubBlockStart.gif
ContractedSubBlock.gif


dot.gif



{




175


InBlock.gif
CreateException();



176


ExpandedSubBlockEnd.gif
}






177


InBlock.gif


catch


(Exception e)



178


ExpandedSubBlockStart.gif
ContractedSubBlock.gif


dot.gif



{




179


ExpandedSubBlockStart.gif
ContractedSubBlock.gif


/**/



///


通过delegate转向工作线程的异常处理






180

InBlock.gif



new


WorkerThreadExceptionHandlerDelegate(



181


InBlock.gif
WorkerThreadExceptionHandler).BeginInvoke(e



182


InBlock.gif
,


null





183


InBlock.gif
,


null


);



184


ExpandedSubBlockEnd.gif
}






185


ExpandedSubBlockEnd.gif
}






186


InBlock.gif



187


ExpandedSubBlockStart.gif
ContractedSubBlock.gif


/**/



///




<summary>





188


InBlock.gif


///


发生主线程异常



189


InBlock.gif


///




</summary>





190


InBlock.gif


///




<param name=”sender”></param>





191


ExpandedSubBlockEnd.gif


///




<param name=”e”></param>






192

InBlock.gif



private




void


btnMainUIThread_Click(


object


sender, System.EventArgs e)



193


ExpandedSubBlockStart.gif
ContractedSubBlock.gif


dot.gif



{




194


ExpandedSubBlockStart.gif
ContractedSubBlock.gif


/**/



///


这里出现一个异常,我们不予捕获,交由全局处理函数






195

InBlock.gif

CreateException();



196


ExpandedSubBlockEnd.gif
}






197


InBlock.gif



198


ExpandedSubBlockStart.gif
ContractedSubBlock.gif


/**/



///




<summary>





199


InBlock.gif


///


发生工作线程异常



200


InBlock.gif


///




</summary>





201


InBlock.gif


///




<param name=”sender”></param>





202


ExpandedSubBlockEnd.gif


///




<param name=”e”></param>






203

InBlock.gif



private




void


btnWorkThread_Click(


object


sender, System.EventArgs e)



204


ExpandedSubBlockStart.gif
ContractedSubBlock.gif


dot.gif



{




205


InBlock.gif
Thread t


=




new


Thread(


new


ThreadStart(DataSave));



206


InBlock.gif
t.Start();



207


ExpandedSubBlockEnd.gif
}






208


ExpandedSubBlockEnd.gif
}






209


ExpandedBlockEnd.gif
}






210


None.gif