日期:2014-05-18 浏览次数:20937 次
? ? 无论写什么方面的程序,异常是不可避免的,而怎么处理涉及的东西则比较多,异常的处理方式,自己的理解分为两个方面的,一种是正常的业务异常,例如银行转帐时金额不够,这类错误一般会直接提示给用户;另一种是系统内部错误,例如银行转帐时,网络中断,这类错误同样也是需要提示给用户,但也是提示系统错误而已,不属于业务异常;无论那种错误,基本都会涉及到异常的捕捉处理和日志记录.现在的系统多属于分层的组件结构,异常更多的是在不同的组件之间传递,所以异常的捕捉和传递也相当重要,很少是由原始的异常发送的地方处理异常.
? ? .net的异常传递处理方式网上有很多规范可以使用,这里不涉及处理异常的顺序或者方式,主要对于异常的传递,典型的处理方式如下:
static void TestException1() { try { DivideZero(); } catch (Exception ex) { throw ex; } }?虽然是同一个异常,他会把异常信息传递给上层,但是会丢失异常真正的堆栈信息,他只会把异常的堆栈定义到当前抛出异常的地方;所以如果需要把原始的异常的堆栈信息抛给上层,则直接使用throw,而不需要任何特殊处理
static void TestException2() { try { DivideZero(); } catch//catch (Exception) { throw; } }
? ? 这是网上推荐的做法,实际上,他的确可以把底层的异常堆栈和异常抛给外层,但是在测试的时候,因为自己的不小心,这种方式还是有个小问题,只是平时很容易忽略掉,如果异常的真实发送地点正是在异常处理快里面,而不是异常处理快里面的函数里面,他也会丢失堆栈信息,这和throw ex处理方式没啥分别,具体原因还有待考证.
? ? 测试源代码
namespace ExceptionDemo { using System; class Program { static void Main(string[] args) { Test(TestException1); Test(TestException2); Test(TestException3); Test(TestException4); Console.ReadLine(); } static void Test( Action action) { try { action(); } catch (Exception ex) { Console.WriteLine(ex); } Console.WriteLine(); } static void TestException1() { try { DivideZero(); } catch (Exception ex) { throw ex; } } static void TestException2() { try { DivideZero(); } catch//catch (Exception) { throw; } } static void TestException3() { try { int a = 0; Console.WriteLine(10 / a); } catch { throw; } } static void TestException4() { try { DivideZero(); } catch (Exception ex) { throw new Exception("处理出错", ex); } } static void DivideZero() { int a = 0; Console.WriteLine(10 / a); } } }
?本地的输出,使用的是vs2008,.net3.5
?
? ? 从上图的红色标记可以看到,即是使用throw,对于代码块里面直接抛出的异常,他一样会丢失相应的堆栈信息.这样看,还是包装一层要安全一点,但是具体原因还不是特别清楚.
?