关于异常处理的最佳实践:
1.所谓人无完人,咱们再写程序的时候不可能手动的try catch住所有的异常,那么对于没有catch住的异常怎么办,还好.net 提供了一个全局的事件用来handle住全局的异常
****对控制台程序而言****************************************
AppDomain.CurrentDomain.UnhandledException += new UnhandledExceptionEventHandler(UnhandledExceptionEventHandler); |
异常处理方式委托到自己定义的方法
static void UnhandledExceptionEventHandler( object sender, UnhandledExceptionEventArgs e) { |
using (System.IO.FileStream fs = new System.IO.FileStream( @"c:\testme.log" , |
System.IO.FileMode.Append, System.IO.FileAccess.Write)) { |
using (System.IO.StreamWriter w = new System.IO.StreamWriter(fs, |
System.Text.Encoding.UTF8)) { |
w.WriteLine(e.ExceptionObject); |
****对于winform有如下的处理方式*****************************************************
Application.ThreadException += new ThreadExceptionEventHandler(Application_ThreadException); |
未捕获异常会产生ThreadException 事件,下面是事件的处理函数
static void Application_ThreadException( object sender, ThreadExceptionEventArgs e) { |
MessageBox.Show(e.Exception.Message, "异常" ,MessageBoxButtons.OK,MessageBoxIcon.Error); |
****asp.net程序稍微有点复杂********************************
一般情况下产生的异常都不会导致asp.net程序终止,只是报个错而已,这是因为,asp.net程序实际上是在后台线程或线程池中运行,产生异常不会致使主线程终止,可以理解为后台产生异常后由asp.net框架自身捕获,处理方式是生成一个黄黄的页面,并且将异常信息以html的格式排列在上面。
那么我们怎么获得这个异常呢,很简单用Server.GetLastError()就能得到这个异常,通常在asp.net的Global.asax文件中提供一个方法Application_Error被委托到异常产生的事件上,我们可以在这里处理全局的未handle的异常,比方说记录到日志 Server.Transfer("")到一个更友好的页面
同学们表示,难道没有异常能直接导致asp.net程序的崩溃,W3WP.exe进程终止?这是必然有的,只要有可以运行的程序,必然有导致其运行不了的状况,那么遇到这种情况该怎么办呢?我怎么捕获这类异常呢?
来先创建一个HttpModule
public class UnhandledExceptionModule : IHttpModule { |
static object _initLock = new object (); |
static bool _initialized = false ; |
public UnhandledExceptionModule() { |
void OnUnhandledException( object o, UnhandledExceptionEventArgs e) { |
using (System.IO.FileStream fs = new System.IO.FileStream( @"c:\testme.log" , |
System.IO.FileMode.Append, System.IO.FileAccess.Write)) { |
using (System.IO.StreamWriter w = new System.IO.StreamWriter(fs, System.Text.Encoding.UTF8)) { |
w.WriteLine(e.ExceptionObject); |
#region IHttpModule Members |
throw new Exception( "The method or operation is not implemented." ); |
public void Init(HttpApplication context) { |
AppDomain.CurrentDomain.UnhandledException += new UnhandledExceptionEventHandler(OnUnhandledException); |
然后在web.config中注册一下下这个handle,在<system.web>节点中
< add name = "UnhandledExceptionModule" type = "WebMonitor.UnhandledExceptionModule" /> |
****上面说了系统抛出的异常,那么我们在做程序的时候要抛出异常怎么办********************
因为现在在写服务端程序的时候,不可能像以前一样返回错误代码,反正大家都认为这种方式不好,而改用遇到错误抛异常出去的方式,客户端程序调用我这个方法注意catch一下就行了,那么我找了半天,发现.net框架里面没有适合我这个异常的异常类,比方说做一个男人类,里面有一个方法叫拉屎,需要接受一个参数叫厕所,然后要判断一下这厕所是男厕还是女厕,是女厕得抛出异常,怎么样.net 不可能有这个异常类吧,处理方式如下,很简单,不解释。
public class SexError:Exception { |
public SexError() : base ( "你很2" ) { |
public SexError( string message) |
public SexError( string message,Exception innerException) |
: base (message, innerException) { |
使用:
public void HappyThing(Tolitle _tl) { |
if (_tl.Sex == "TrueMan" ) { |
public string Sex { get ; set ; } |
public class ManTolitle : Tolitle { |
客户端调用
public void clientMethod() { |
Tolitle _tolitle = new ManTolitle(); |
Man _FoolMan = new Man(); |
_FoolMan.HappyThing(_tolitle); |
showmessage( "强烈谴责楼主去女厕不带我们" ); |
最后说一下 throw和thow ex; 区别,广大同学比较喜欢用thow ex这个很不好的方式,他把原始异常信息截断了,包装成了新的异常,表现具体是堆栈信息显示是调用抛出异常的方法的栈信息,而不是直接是抛出异常产生处的栈信息,在堆栈最下面会显示个【外部方法】,灰色的,点不了所以不能准确判断异常的信息。
总之如果要继续上抛异常用throw好过throw catch住的异常
多线程异常,只要理解跨线程调用,很容易找到方法,先handle住全局异常
Application.ThreadException += new ThreadExceptionEventHandler( MainUIThreadExceptionHandler); |
自己定义处理方法
public static void MainUIThreadExceptionHandler(Exception ex) |
MainUIThreadExceptionHandler( null , new |
ThreadExceptionEventArgs(ex)); |
public static void MainUIThreadExceptionHandler( object |
sender, ThreadExceptionEventArgs e) |
+ ( char )13 + e.Exception.Message |
, MessageBoxDefaultButton.Button1 |
, MessageBoxOptions.ServiceNotification); |
}