一、MSDN描述
Exception 类: 表示在应用程序执行期间发生的错误
命名空间 : System
程序集: mscorlib.dll
继承关系:
常用属性(含字段)和方法:1. 属性
Message 描述当前异常的消息StackTrace 获取调用堆栈上直接帧的字符串表示形式(说白了就是导致异常的函数调用栈信息)Source 获取导致异常的应用程序或对象名称TargetSite 获取引发异常的方法其中 StackTrace 属性最有用
2.方法
ToString 返回当前异常的字符串表示形式(重写Object.ToString())
备注:
1. Exception 的常见用法 try-catch 块(用try包裹待执行的代码,用catch来捕捉待执行代码出现的异常)
2. try-catch-finally 块,即使异常发生 finally 也会进,finally中放清理资源的代码
3. using语句会自动生成try-finally 的IL
二、一些建议
1.不要返回错误码(用返回错误码表示异常是Win32时期的特色,在.NET时代这是不允许的)
2.要通过抛出异常的方式来报告失败
3.不要轻易吃掉异常,如果是异常就应该抛出
4.不要把异常作为业务逻辑分支
try{ 逻辑A }catch{ 逻辑B}后续逻辑
5. 不要让公有成员根据某个选项来决定是否抛出异常
public Type GetType(string name,bool throwOnError); // 不好的设计
像上面的API设计通常反映出框架设计者的无力做出决定。一个方法要么成功,要么失败,而失败了就应该抛出异常。框架设计者未能做出决定,这迫使API调用者来决定,但由于调用者并不了解API的实现细节,因此他们更难做出正确的决定
6.异常的抛出应该选择最具有描述性的一个(如系统没有该异常,考虑自定义一个异常)
如try 语句块的功能是解析某参数,那么catch 块就应该优先用 ArgumentException (参数异常),最后再用 Exception 来捕获其他异常
try{}catch(ArgumentException ex){}catch(Exception ex){}
7. 用 Try-Parse 模式
如 DateTime.TryParse 这是综合了性能和异常处理的好东西,比直接 DateTime.Parse 好
三、使用log4net记录异常信息
官网:
1. 配置 log4net.config
修改上面的 <param name="File" value="D:\log4netDemo\log4netDemoApp.log" /> 改为你想要的日志存放路径
注意这个 log4net.config 应该编译输入到程序目录(如:bin\Debug)
2. 在主程序启动类中写如下代码
private const string c_logConfig = "log4net.config"; private log4net.ILog _log = log4net.LogManager.GetLogger(typeof(Program));static void Main(string[] args){ using (Stream stream = File.OpenRead(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, c_logConfig))) { XmlConfigurator.Configure(stream); }。。。}
3. 使用
_log.Info("Start");_log.Error("捕捉到异常{0}", ex);
更多log4net方法,查看API文档
四、全局异常捕获
AppDomain.CurrentDomain.UnhandledException
static void Mian(){ AppDomain.CurrentDomain.UnhandledException += new UnhandledExceptionEventHandler(CurrentDomain_UnhandledException);}static void CurrentDomain_UnhandledException(object sender, UnhandledExceptionEventArgs e){ Exception error = (Exception)e.ExceptionObject; _log.Error("MyHandler caught : " + error.Message);}
WinForm、WPF、ASP.NET 均有全局异常捕获
五、多线程中的异常捕获
错误的捕获方式:
1 static void ThreadException1() 2 { 3 var t = new Thread(() => { throw new Exception("线程抛出异常"); }); 4 try 5 { 6 t.Start(); 7 } 8 catch (Exception ex) 9 {10 // 这样捕获不到线程异常11 _log.Error("捕获到线程异常 {0}", ex);12 }13 }
正确的捕获方式:
1 static void ThreadException2() 2 { 3 var t = new Thread(() => 4 { 5 try 6 { 7 throw new Exception("线程抛出异常"); 8 } 9 catch (Exception ex)10 {11 _log.Error("捕获到线程异常 {0}", ex);12 }13 });14 t.Start();15 }
六、系统事件查看器
这是一个很有用的功能,估计还有不少同学不知道
右键计算机(我的电脑) ==> 管理 ==> 计算机管理
本文代码