惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

博客园 - 三生石上(FineUI控件)
O
OpenAI News
WordPress大学
WordPress大学
P
Proofpoint News Feed
J
Java Code Geeks
G
Google Developers Blog
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
The Register - Security
The Register - Security
Engineering at Meta
Engineering at Meta
H
Help Net Security
人人都是产品经理
人人都是产品经理
Vercel News
Vercel News
N
Netflix TechBlog - Medium
F
Full Disclosure
U
Unit 42
Latest news
Latest news
N
News and Events Feed by Topic
Threat Intelligence Blog | Flashpoint
Threat Intelligence Blog | Flashpoint
I
InfoQ
L
LINUX DO - 最新话题
T
Threat Research - Cisco Blogs
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
爱范儿
爱范儿
K
Kaspersky official blog
Google Online Security Blog
Google Online Security Blog
小众软件
小众软件
I
Intezer
V
V2EX
S
SegmentFault 最新的问题
C
CERT Recently Published Vulnerability Notes
阮一峰的网络日志
阮一峰的网络日志
Security Archives - TechRepublic
Security Archives - TechRepublic
Recent Announcements
Recent Announcements
C
Check Point Blog
C
Cyber Attacks, Cyber Crime and Cyber Security
Recorded Future
Recorded Future
博客园 - Franky
Project Zero
Project Zero
S
Securelist
Attack and Defense Labs
Attack and Defense Labs
Spread Privacy
Spread Privacy
The Hacker News
The Hacker News
T
The Blog of Author Tim Ferriss
Google DeepMind News
Google DeepMind News
aimingoo的专栏
aimingoo的专栏
博客园 - 叶小钗
NISL@THU
NISL@THU
云风的 BLOG
云风的 BLOG
S
Secure Thoughts
Exploit-DB.com RSS Feed
Exploit-DB.com RSS Feed

博客园 - 兵

CryptoAPI与.NET数字签名类的交互问题 Firefox中Iframe的blur与focus事件问题 .NET中几种基本的线程同步方法 为什么说WinForm的控件只能在主线程中创建和调用 C#与Native C++互相访问 PHP5中的引用 Windows版的PDO太衰了 Framework里某些类型成员方法的一点疑惑 发现一个FireFox的问题 C#中COM操作(二)---接口查询 C#中COM操作(一)---实例化 非弹出式的模态对话框的背景遮罩 DOTNET事件拾遗 CSS开发辅助工具:Internet Explorer Developer Toolbar 另外一种高效地判断奇数和偶数的方法 如何利用客户端缓存对网站进行优化? 一个多表查询引出的问题(2) 类的成员初始化顺序 一个多表查询引出的问题(1)
C#异常处理的方式
· 2012-06-26 · via 博客园 - 兵

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;