bindsang

工作五年,长期从事于asp.net方面的编程,业余爱好VC编程,温和、谦虚、自律、自信、善于与人交往沟通
随笔 - 35, 文章 - 0, 评论 - 64, 阅读 - 64928
  博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理
< 2025年3月 >
23 24 25 26 27 28 1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 29
30 31 1 2 3 4 5

C#异常处理的方式

Posted on     阅读(2690)  评论(2编辑  收藏  举报

 

C#异常处理的方式

 

c#中所有可以被抛出的异常都是直接或间接继承自System.Exception

 

支持的捕获异常的语句块如下:

try … catch

try … catch … finally

try… finally

 

c#代码块中生成异常堆栈信息的时机不是在throw语句执行的地方,而是在第一次捕获的地方

 

以上三种方式中 try ... finally一定不会影响堆栈信息

可能会影响的地方主要集中在catch块中

 

catch子句声明方式又有以下几种

 

catch{}

catch(Exception){}

catch(Exception ex){}

 

这三种写法从捕获异常的能力上来说基本上是等效

第三种方式只是让编写代码的人可以使用异常参数,如果不使用异常参数的话可以用前面两种,第二种只是更加明确的指出了捕获的是Exception或者是从Exception继承的异常

 

catch块内可以再次抛出异常,抛出时可以支持下面几种方式

 

throw;

throw ex; // ex来自于catch(Exception ex)

throw new SomeException();

 

后面两种情况是一样的, stack trace认为你catch到的异常已经被处理了,只不过处理过程中又抛出新的异常,这时候stack trace就把throw 后的那个异常实例当作错误根源了。之前的堆栈信息全部会清除掉

第一种方式网上和MSDN上都说可以保留堆栈信息。经测试发现不全是如此:

Debug版本下,生成的代码在执行没有任何优化,直接使用throw;这种方式的确是能保留堆栈信息。这个时候的堆栈信息就好像是在try块内部异常产生的地方就记录好了一样。

Release下,输出的信息中只包含了从捕获位置开始向上的堆栈信息。即从异常源发生位置到第一次catch块捕获发生之间的堆栈信息都不存在了

 

总结如下:

以前的异常信息中有出错的点很容易就找到了,那是因为正巧异常源与第一次捕获的地方很接近

否则的话越是在调用的最上层捕获到异常,越不容易找到异常源在什么位置(这里都是在Release条件下)

Release版本下,异常越早捕获,越能精确定位出错位置,越晚捕获,从堆栈中获得的获得的有效信息也越少,即使是用了throw;这样的方式也一样

严格禁止 下面这种写法:

try{

         // do

}

catch(Exception ex)

{

throw ex;

}

如有必要需改用 throw; 或者 throw new SomeException(msg, ex); 这样的形式

 

如果是捕获了异常不想再次抛出(一般用在捕获到的异常在预期范围内,已经有相应的处理方式了),最好是能记录日志,表示发生过异常

 

 

附上一个测试:

Release 使用throw;

Release 使用throw ex;

 

 

Release下更极端的例子去掉了除最外层外所有的try…catch

 

 

 

Debug 使用throw;

 

 

Debug 使用throw ex;

 

 

编辑推荐:
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
阅读排行:
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 分享 3 个 .NET 开源的文件压缩处理库,助力快速实现文件压缩解压功能!
· Ollama——大语言模型本地部署的极速利器
· [AI/GPT/综述] AI Agent的设计模式综述
点击右上角即可分享
微信分享提示