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

推荐订阅源

Martin Fowler
Martin Fowler
CTFtime.org: upcoming CTF events
CTFtime.org: upcoming CTF events
A
About on SuperTechFans
Apple Machine Learning Research
Apple Machine Learning Research
The Register - Security
The Register - Security
Vercel News
Vercel News
H
Hackread – Cybersecurity News, Data Breaches, AI and More
人人都是产品经理
人人都是产品经理
MyScale Blog
MyScale Blog
云风的 BLOG
云风的 BLOG
博客园_首页
U
Unit 42
T
Tailwind CSS Blog
G
GRAHAM CLULEY
F
Full Disclosure
V
Vulnerabilities – Threatpost
T
Tenable Blog
月光博客
月光博客
P
Privacy & Cybersecurity Law Blog
P
Privacy International News Feed
K
Kaspersky official blog
Scott Helme
Scott Helme
cs.AI updates on arXiv.org
cs.AI updates on arXiv.org
N
News and Events Feed by Topic
T
The Exploit Database - CXSecurity.com
N
News and Events Feed by Topic
有赞技术团队
有赞技术团队
Recent Commits to openclaw:main
Recent Commits to openclaw:main
L
LINUX DO - 最新话题
Recorded Future
Recorded Future
Application and Cybersecurity Blog
Application and Cybersecurity Blog
Help Net Security
Help Net Security
The GitHub Blog
The GitHub Blog
Cisco Talos Blog
Cisco Talos Blog
SecWiki News
SecWiki News
P
Proofpoint News Feed
Security Latest
Security Latest
cs.CL updates on arXiv.org
cs.CL updates on arXiv.org
罗磊的独立博客
S
Security Affairs
M
MIT News - Artificial intelligence
L
LINUX DO - 热门话题
美团技术团队
Simon Willison's Weblog
Simon Willison's Weblog
T
Threat Research - Cisco Blogs
Stack Overflow Blog
Stack Overflow Blog
Forbes - Security
Forbes - Security
Hugging Face - Blog
Hugging Face - Blog
博客园 - Franky
V
Visual Studio Blog

博客园 - 兵

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;