前言

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

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. 为什么 Linux Mint 比 Ubuntu好?

    Linux Mint由Linux Mint Team团队于2006年开始发行,是一份基于Debian和Ubuntu的Linux发行版.其目标是提供一种更完整的即刻可用体验,这包括提供浏览器插件.多媒体 ...

  2. 由于抽签HT For Web ComboBox下拉框组件

    传统HTML5的下拉框select仅仅能实现简单的文字下拉列表,而HT for Web通用组件中ComboBox不仅可以实现传统HTML5下拉框效果,并且可以在文本框和下拉列表中加入自己定义的小图标, ...

  3. 解决opengl计算顶点的法线问题

    因为需要的论文,最近开始学习OpenGL.由于刚入门的初学者有这么总会遇到很多问题,. 这些天,好不容易才OpenGL个问题弄明确了. 几点迷惑: 在网上百度.发现非常多求平面法向量的介绍以及程序.后 ...

  4. 第三十讲:Android之Animation(五)

    天行健,君子以自强不息.--<周易·乾·象> 本讲内容:逐帧动画 Frame Animation 逐帧动画 Frame Animation就是说一帧一帧的连起来播放就变成了动画,和放电影的 ...

  5. Swift使用单个案件管理FMDB数据库

    下班... 抢 我曾经Swift使用单一个案管理FMDB数据库的方法共享出来: // Created by 秦志伟 on 14-6-12. import UIKit class ZWDBManager ...

  6. Codeforces 479E Riding in a Lift(dp)

    题目链接:Codeforces 479E Riding in a Lift 题目大意:有一栋高N层的楼,有个无聊的人在A层,他喜欢玩电梯,每次会做电梯到另外一层.可是这栋楼里有个秘 密实验室在B层,所 ...

  7. ENode框架Conference案例转载

    ENode框架Conference案例分析系列之 - Quick Start 前言 前一篇文章介绍了Conference案例的架构设计,本篇文章开始介绍Conference案例的代码实现.由于代码比较 ...

  8. 软体project(四)——一生

    软件生存周期是软件project中的一个重要概念,把整个生存周期划分为若干个阶段,是实现软件生产project化的重要步骤. 软件的生存周期一般划分为软件计划.软件开发和软件执行三个时期,例如以下图: ...

  9. ASP.NET MVC+EF框架+EasyUI实现权限管理系列(1)-框架搭建

    原文:ASP.NET MVC+EF框架+EasyUI实现权限管理系列(1)-框架搭建 ASP.NET MVC+EF框架+EasyUI实现权限管系列 (开篇) 前言:这篇博客开始我们便一步一步的来实现这 ...

  10. Arcgis For Android之GPS定位实现

    翻开曾经做的东西,看了看,非常多从逻辑上比較乱,对之做了改动,完毕后实现的效果为: MapActivity源码例如以下: package com.lzugis.map; import java.io. ...