读书笔记—CLR via C#异常和状态管理
前言
这本书这几年零零散散读过两三遍了,作为经典书籍,应该重复读反复读,既然我现在开始写博了,我也准备把以前觉得经典的好书重读细读一遍,并且将笔记整理到博客中,好记性不如烂笔头,同时也在写的过程中也可以加深自己理解的深度,当然同时也和技术社区的朋友们共享
Tips
- vs调试catch块时,监视窗口变量: $exception 查看当前抛出的异常对象
- 异常的catch是自上而下,回溯调用栈,如果未找到,就抛出未处理异常
- 异常的执行顺序:先执行body,再执行catch,最后执行finally
- 堆栈异常的执行顺序:ParentBody ChildBody ChildCatch ChildFinally ParentCatch ParentFinally
- .NET 4版本及后续版本中,可向AppDomain的FirstChanceException登记Appdomain中发生的第一次异常捕获,它发生在CLR搜索任何catch块之前
- finally中的代码保证会被执行,无论异常是否发生(用Win32函数TerminateThread杀死线程,或者用Winb32函数TerminateProcess或System.Environment的FailFast方法杀死进程,finally块不会执行。当然进程终止后,Windows会清理进程使用的所有资源)
- 如果catch或者finally中抛出异常,原有异常会丢失,新的异常继续向上回溯
- CLR只能捕获CLS相容(从Exception派生的异常被认为时CLS相容的)的异常,如果C#调用另一种编程语言的方法,抛出非CLS相容的异常,那么C#代码不能捕捉这个异常,这会有一些安全隐患
- 非CLS相容的一个异常被抛出时,CLR会自动构造RuntimeWrappedException类的实例,并初始化该实例的私有字段,使之引用实际抛出的对象。这样一来CLR就将非CLS相容的异常转变成了CLS相容的异常。所以任何能捕捉Exception类型的代码,都能捕捉非CLS相容的异常,从而消除了安全隐患
- 在C#2.0之后,Catch可以捕捉CLS相容和不相容的任何异常(Exception),而如果直接catch{} ,所以版本的C#都可以捕捉CLS相容和不相容异常
- 如果要兼容CLR旧的行为[assembly:RuntimeCompatibility(WrapNonExceptionThrows=false)]
- 一个异常抛出时,CLR会在内部记录throw指令的位置(抛出位置),一个catch捕捉到异常时,CLR又会记录异常的捕捉位置
- 在catch块内访问被抛出的异常对象的StackTrace属性,负责实现该属性的代码会调用CLR内部代码,创建一个字符串指出从异常抛出位置道异常捕捉位置的所有方法
- 在catch中重写throw e会重置异常的起点(重置堆栈的起点),不符合编码规范,如果仅仅使用throw 则OK
- 如果代码方法被内联,可能导致异常堆栈跟踪不准确对应到源代码,如果要防止JIT优化内联,使用编译器开关 /debug 或者[System.Runtime.CompilerServices.MethodImplAttribute(MethodImplOptions.NoInling)]
- 异常自身字符串消息可以包含详细的技术细节,用于跟踪调试,但这些消息不应该直接让应用层捕获,不应该向最终用户显示
- FCL的异常消息都使用了本地化字符串,开发人员可以根据实际情况考虑
- 设计和处理异常时,通常要牺牲可靠性来换取开发效率
- 尽量避免捕捉System.Exception然后允许应用程序继续允许,一个很大的问题是状态可能遭受破坏
- lock, using和foreach语句,都使用了try/finally块,重写析构器时,编译器也会自动生成try/finally
- 异步编程模型中异常会被“吞噬”然后重新抛出一样的异常
- 编码建议,一般捕获并处理异常之后,不要把它吞噬,单独使用throw,抛出相同的异常
- 关于异常的实践规范,可以好好思考一下,比如定义应用层异常、业务层异常、服务异常,通讯异常,然后将FCL的异常“吞噬”记录日志
- dynamic对象调用方法如果失败,会抛出TargetInvocationException异常。最初抛出的异常会正常地在调用栈中向上传递。这是使用C#的dynamic基元类型代替反射的一个很好的理由。(如果使用反射来调用方法,方法内的异常不能被正常捕获)
- 未捕获未处理的异常会写入Windows日志中
- 分布式程序中,尽量少的暴露异常信息,如果堆栈信息暴露,可能服务器中的信息被泄露
- 调试异常时,关注VS菜单“调试”-“异常”,可以强制引发某些异常发生,防止被“吞噬”(即使它被Catch)
- 另外异常处理的性能影响,能避免就避免,比如,如果有Try前缀的方法,尽量使用Try前缀的方法(不过Try的方法依然可能会抛异常,比如style参数无效,会抛出ArgumentException,另外还有可能抛出OutMemoryException异常)
- 如果要在抛出非预期的异常时维护状态,CER很有用。这种异常也称异步异常。CLR加载程序集时,在AppDomain的Load堆中创建一个类型对象,调用类型的静态构造器,并将IL代码JIT编译成本地代码。如果操作失败,CLR抛出异常报告失败。(很多隐式的非一致性的异常,导致无法预料)
- CER, PrepareConstrainedRegions很特别的方法,JIT编译器如果发现一个try块前调用这个方法,会提前编译与try关联的catch和finally块中的代码。JIT编译器会加载任何程序集,创建任何类型对象,调用任何静态构造器,并对任何方法JIT编译。如果其中任何操作造成异常,这个异常会在线程进入try块之前发生。JIT编译器提前准备方法时,还会遍历调用图,前提时方法一个用了[ReliabilityContractAttribute]而且传递Consistency.WillNotCorruptState或Consistency.MayCorruptInstance枚举成员。这是由于加入方法会损坏AppDomain或进程状态,CLR便无法对状态一致性做出保证
- 可以调用RuntimeHelper的PrepareMethod手动准备方法
- CER文章参考:http://www.cnblogs.com/Ninputer/archive/2006/06/30/439757.html
未捕获的异常处理
- Winform, OnThreadException虚方法及Application的ThreadException事件
- WPF程序Application的DispatcherUnhandledExceptions和System.WIndows.Therading.Dispatcher的UnhandledException和UnhandledExceptionFilter事件
- 对于SIlverlight,System.Window.Application的UnhandledExceptoin事件
- ASP.NET程序,System.Web.HttpApplication的Error事件
- 对于WCF,System.ServiceModel.Dispatcher.ChnnelDispatche的ErrorHandlers属性
契约式编程
有时间我好好整理一下这方面的东西,毕竟一种编程习惯的培养,需要慢慢积累去逐渐使用新的思维
参考文章:
http://www.infoq.com/cn/news/2009/02/Code-Contracts-.NET
http://www.cnblogs.com/lucifer1982/archive/2009/03/21/1418642.html
读书笔记—CLR via C#异常和状态管理的更多相关文章
- [CLR via C#]异常和状态管理
当CLR检测到某个正在运行的.NET应用程序处于一种特殊的正常执行顺序被打断的状态时,会生成一个异常对象来表示这个错误,并将此对象在方法调用堆栈中向上传送.如果一个程序引发了一个异常却没有处理,CLR ...
- 对CLR异常和状态管理的一点理解
一:自己的感悟 今天读到<CLR via C#>的异常和状态管理这一章,作者给出了关于异常处理的诸多建议,里面有一些建议自己深有体会,比如说使用可靠性换取开发效率这一节.之前自己对异常怎么 ...
- 【C#进阶系列】20 异常和状态管理
异常就是指成员没有完成它的名称所宣示的行动. public class Girl { public string Name { get; set; } } public class Troy{ Gir ...
- 《Linux内核设计与实现》读书笔记(十一)- 定时器和时间管理【转】
转自:http://www.cnblogs.com/wang_yb/archive/2013/05/10/3070373.html 系统中有很多与时间相关的程序(比如定期执行的任务,某一时间执行的任务 ...
- 读书笔记—CLR via C#委托和attribute
前言 这本书这几年零零散散读过两三遍了,作为经典书籍,应该重复读反复读,既然我现在开始写博了,我也准备把以前觉得经典的好书重读细读一遍,并且将笔记整理到博客中,好记性不如烂笔头,同时也在写的过程中也可 ...
- 读书笔记—CLR via C#线程25-26章节
前言 这本书这几年零零散散读过两三遍了,作为经典书籍,应该重复读反复读,既然我现在开始写博了,我也准备把以前觉得经典的好书重读细读一遍,并且将笔记整理到博客中,好记性不如烂笔头,同时也在写的过程中也可 ...
- 读书笔记—CLR via C#反射
前言 这本书这几年零零散散读过两三遍了,作为经典书籍,应该重复读反复读,既然我现在开始写博了,我也准备把以前觉得经典的好书重读细读一遍,并且将笔记整理到博客中,好记性不如烂笔头,同时也在写的过程中也可 ...
- 读书笔记—CLR via C#章节11-13
前言 这本书这几年零零散散读过两三遍了,作为经典书籍,应该重复读反复读,既然我现在开始写博了,我也准备把以前觉得经典的好书重读细读一遍,并且将笔记整理到博客中,好记性不如烂笔头,同时也在写的过程中也可 ...
- 读书笔记—CLR via C#章节4-7
前言 这本书这几年零零散散读过两三遍了,作为经典书籍,应该重复读反复读,既然我现在开始写博了,我也准备把以前觉得经典的好书重读细读一遍,并且将笔记整理到博客中,好记性不如烂笔头,同时也在写的过程中也可 ...
随机推荐
- 为什么 Linux Mint 比 Ubuntu好?
Linux Mint由Linux Mint Team团队于2006年开始发行,是一份基于Debian和Ubuntu的Linux发行版.其目标是提供一种更完整的即刻可用体验,这包括提供浏览器插件.多媒体 ...
- 由于抽签HT For Web ComboBox下拉框组件
传统HTML5的下拉框select仅仅能实现简单的文字下拉列表,而HT for Web通用组件中ComboBox不仅可以实现传统HTML5下拉框效果,并且可以在文本框和下拉列表中加入自己定义的小图标, ...
- 解决opengl计算顶点的法线问题
因为需要的论文,最近开始学习OpenGL.由于刚入门的初学者有这么总会遇到很多问题,. 这些天,好不容易才OpenGL个问题弄明确了. 几点迷惑: 在网上百度.发现非常多求平面法向量的介绍以及程序.后 ...
- 第三十讲:Android之Animation(五)
天行健,君子以自强不息.--<周易·乾·象> 本讲内容:逐帧动画 Frame Animation 逐帧动画 Frame Animation就是说一帧一帧的连起来播放就变成了动画,和放电影的 ...
- Swift使用单个案件管理FMDB数据库
下班... 抢 我曾经Swift使用单一个案管理FMDB数据库的方法共享出来: // Created by 秦志伟 on 14-6-12. import UIKit class ZWDBManager ...
- Codeforces 479E Riding in a Lift(dp)
题目链接:Codeforces 479E Riding in a Lift 题目大意:有一栋高N层的楼,有个无聊的人在A层,他喜欢玩电梯,每次会做电梯到另外一层.可是这栋楼里有个秘 密实验室在B层,所 ...
- ENode框架Conference案例转载
ENode框架Conference案例分析系列之 - Quick Start 前言 前一篇文章介绍了Conference案例的架构设计,本篇文章开始介绍Conference案例的代码实现.由于代码比较 ...
- 软体project(四)——一生
软件生存周期是软件project中的一个重要概念,把整个生存周期划分为若干个阶段,是实现软件生产project化的重要步骤. 软件的生存周期一般划分为软件计划.软件开发和软件执行三个时期,例如以下图: ...
- ASP.NET MVC+EF框架+EasyUI实现权限管理系列(1)-框架搭建
原文:ASP.NET MVC+EF框架+EasyUI实现权限管理系列(1)-框架搭建 ASP.NET MVC+EF框架+EasyUI实现权限管系列 (开篇) 前言:这篇博客开始我们便一步一步的来实现这 ...
- Arcgis For Android之GPS定位实现
翻开曾经做的东西,看了看,非常多从逻辑上比較乱,对之做了改动,完毕后实现的效果为: MapActivity源码例如以下: package com.lzugis.map; import java.io. ...