前言

这本书这几年零零散散读过两三遍了,作为经典书籍,应该重复读反复读,既然我现在开始写博了,我也准备把以前觉得经典的好书重读细读一遍,并且将笔记整理到博客中,好记性不如烂笔头,同时也在写的过程中也可以加深自己理解的深度,当然同时也和技术社区的朋友们共享

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#异常和状态管理的更多相关文章

  1. [CLR via C#]异常和状态管理

    当CLR检测到某个正在运行的.NET应用程序处于一种特殊的正常执行顺序被打断的状态时,会生成一个异常对象来表示这个错误,并将此对象在方法调用堆栈中向上传送.如果一个程序引发了一个异常却没有处理,CLR ...

  2. 对CLR异常和状态管理的一点理解

    一:自己的感悟 今天读到<CLR via C#>的异常和状态管理这一章,作者给出了关于异常处理的诸多建议,里面有一些建议自己深有体会,比如说使用可靠性换取开发效率这一节.之前自己对异常怎么 ...

  3. 【C#进阶系列】20 异常和状态管理

    异常就是指成员没有完成它的名称所宣示的行动. public class Girl { public string Name { get; set; } } public class Troy{ Gir ...

  4. 《Linux内核设计与实现》读书笔记(十一)- 定时器和时间管理【转】

    转自:http://www.cnblogs.com/wang_yb/archive/2013/05/10/3070373.html 系统中有很多与时间相关的程序(比如定期执行的任务,某一时间执行的任务 ...

  5. 读书笔记—CLR via C#委托和attribute

    前言 这本书这几年零零散散读过两三遍了,作为经典书籍,应该重复读反复读,既然我现在开始写博了,我也准备把以前觉得经典的好书重读细读一遍,并且将笔记整理到博客中,好记性不如烂笔头,同时也在写的过程中也可 ...

  6. 读书笔记—CLR via C#线程25-26章节

    前言 这本书这几年零零散散读过两三遍了,作为经典书籍,应该重复读反复读,既然我现在开始写博了,我也准备把以前觉得经典的好书重读细读一遍,并且将笔记整理到博客中,好记性不如烂笔头,同时也在写的过程中也可 ...

  7. 读书笔记—CLR via C#反射

    前言 这本书这几年零零散散读过两三遍了,作为经典书籍,应该重复读反复读,既然我现在开始写博了,我也准备把以前觉得经典的好书重读细读一遍,并且将笔记整理到博客中,好记性不如烂笔头,同时也在写的过程中也可 ...

  8. 读书笔记—CLR via C#章节11-13

    前言 这本书这几年零零散散读过两三遍了,作为经典书籍,应该重复读反复读,既然我现在开始写博了,我也准备把以前觉得经典的好书重读细读一遍,并且将笔记整理到博客中,好记性不如烂笔头,同时也在写的过程中也可 ...

  9. 读书笔记—CLR via C#章节4-7

    前言 这本书这几年零零散散读过两三遍了,作为经典书籍,应该重复读反复读,既然我现在开始写博了,我也准备把以前觉得经典的好书重读细读一遍,并且将笔记整理到博客中,好记性不如烂笔头,同时也在写的过程中也可 ...

随机推荐

  1. Android使用HttpClient方法和易错问题

    HttpClient为Android开发人员提供了跟简洁的操作Http网络连接的方法,在连接过程中也有两种方式,get和post,先看一下怎样实现的 默认是get方式 //先将參数放入List,再对參 ...

  2. ExtJS4 动态生成grid出口excel(纯粹的接待)

    搜索相当长的时间,寻找一些样本,因为我刚开始学习的原因,大多数人不知道怎么用.. 他曾在源代码.搞到现在终于实现了主下载.. 表的采集格不重复下载一个小BUG,一个使用grid初始化发生的BUG 以下 ...

  3. UVa 10285 - Longest Run on a Snowboard

    称号:给你一个二维矩阵,找到一个点.每一个可以移动到的位置相邻的上下,求最长单调路径. 分析:贪婪,dp.搜索. 这个问题是一个小样本,我们该怎么办. 这里使用贪心算法: 首先.将全部点依照权值排序( ...

  4. 如何生成可变表头的excel(转)

    1.实现功能: 传入一个表头和数据,将数据导入到excel中. 为了便于项目的扩展,数据传入通过泛型集合传入,获取数据时,通过反射的方式获取,这样无论你的表头是多少项,我都能很方便的生成.另外为了便于 ...

  5. linux文章(11)---umask和chmod

    一.用途 文将介绍linux环境下有关文件訪问模式相关的命令.         umask用来设置默认的文件訪问模式屏蔽值:chmod用来改动文件的訪问模式.         本文将选取ubuntu1 ...

  6. 开始折腾cocos2d-x,使用批处理来创建项目

    开始服用的时间来学习cocos2d-x该,尽管C和C++另外不咋.只是学习和记忆可能是更深层次的,现在发展: so从今天开始正式决定学会与自己的业余时间折腾吧,仅这51什么.昨天,在开发环境中建,Vi ...

  7. JAVA转让JS功能

    今天,在发展中使用js和Java互动.通常我们使用更多的是js转让Java方法.可以使用dwr.Ajax.jquery.突然发现Java转让js然后,我真的没见过,今天,互联网提供以下信息,顺便总结: ...

  8. ClassLoader—流程观察程序执行类加载-verbose:class

    当调试器,有时你需要看到程序加载的类.记忆的恢复情况.本地接口调用,等等..这时候就需要-verbose命令. 在myeclipse能够通过右键设置(例如以下).也能够在命令行输入java -verb ...

  9. 2014年最新的辛星html、css教程打包公布了,免积分,纯PDF(还有PHP奥)

    首先说一下,这个教程是我的全部的博客的精华,我整理了两天之后才做出的这个pdf文档,累死我了,以下免积分给大家,希望大家可以不吝指正,提出它的一些不足什么的,谢谢啦: 以下就是它的下载地址了:2014 ...

  10. iOS 开发小技巧

    1.Xcode配置 1.1> 安装Alcatraz包管理器 打开Terminal终端命令行 curl -fsSL https://raw.github.com/supermarin/Alcatr ...