.NET 异常处理
没有不出错的软件
从不出错的软件从某种程度上讲是不可能的! 和普通人的观念相反, 创造可信赖的, 健壮的
软件并不是一件不可能的事情。 大部分的商业软件,在长时间可以无重大故障的
工作,但它们并非没有任何的错 误,只是拥有低出错率,你可以迅速理解出错原因然后快速搞定它,并且,它不 会因为外部错误而毁坏数据。 软件中有错误是可以原谅的, 甚至是可以预料到的; 不可原谅的是您无法解决一个复发的错误,仅仅是因为您没用足够的信息。 另外,如果希望成功避免发生错误,就必须要求开发人员正确对待错误。
做好最坏的打算
所有代码的书写,你应该认为,它是会发生错误的。如果太过于相信自己, 往往会导致错误没有被处理, 因此也就无法或者非常困难得去获得错误的详细信 息。
不要相信外部数据
外部数据是不可相信的。 不管这些数据是来自寄存器、 数据库、 硬盘、 socket、 文件或者是键盘,它们都必须被检查,只有这样你才可以去使用它们。 唯一可信赖的外部设施是:显示器、鼠标和键盘。
不要理所当然
举个例子,你打开一个 TXT 文件并修改后,希望原地保存,因此往往理所当 然地认为,能打开即能保存。然而,该文件可能是只读的,又或者所在驱动器只 读,甚至磁盘空间不够。如果你理所当然,那程序也就理所当然地出错了。
合理使用.NET 异常处理机制 合理使用
当你摆正观念以后,就可以使用.
NET 完善的异常处理机制,来抒写安全的代 码。事实上,并非掌握了 try{}catch{}语法后,就能抒写安全的代码。其中非 常多需要注意的事项。什么时候 try?怎么 try?怎么 catch,都是可以商酌的。 我这里介绍的仅仅是比较好的方法。
不要抛出 new Exception()
Exception 是一个非常大的类, 如果没有 side-effect(副作用) 很难去捕获。 , 引用你自己的异常类,但是使它继承自 AppliationException。通过这种方法, 你可以设计一个专门的异常捕获程序去捕获框架抛出的异常, 同时
设计另一个异 常捕获程序来处理自己抛出的异常。
每个线程要有单独的 catch (Exception ex)语句 语句
在你的应用程序中,普通的异常处理应该被集中解决。每个线程需要一个单 独的 try/catch 模块,否则,你将会丢失异常导致非常难处理的问题的出现。当 一个应用程序启动若干线程去做一些后台处理时, 通常你需要创建一个用来存储 处理结果的类。不要忘记添加用来存储可能发生的异常的区域,否则在主线程中 你将无法与之
通信。
要记录 Exception 的全部信息
在捕获错误以后,应该记录的是 Exception.ToString(),而不仅是 Exception.M
essage。Exception.ToString()将会给你一个堆栈跟踪内部的异常 和信息。通常,这个信息是及其珍贵的,如果你仅记录 Exception.Message,你 将会仅仅获得一些没用的信息。
要有清理代码
不要忽略的一件事是 try/finally 模块如何使你的代码变得更加可读与健 壮,这是处理代码的巨大作用所在。
举个例子,假设你需要从一个临时文件中阅读一些临时信息,然后以字符串 的形式返回它。不管发生什么,你都必须删除这一文件。这样的返回处理功能需 要 try/finally 模块来完成。
try { string fileContents; using (StreamReader sr = new StreamReader(FileName)) { fileContents = sr.ReadToEnd(); } File.Delete(FileName); return fileContents; } catch (Exception ex) { //错误处理 } finally { File.Delete(FileName); }
经常使用 using
仅仅在一个对象上调用 Dispose()函数是远远不够的。关键字 using 将会阻 止资源泄漏即使在有异常出现的地方。从上面的例子我们也可以看到这个好 处。
当再次抛出异常时不要清空堆栈追踪
堆栈追踪是一个异常携带的最有用的信息之一。经常,我们需要在 catch 模 块中,放入一些异常