1.try catch finally
try中包含的代码通长包含需要清理资源的代码,或者从异常中恢复,或者会抛出异常的代码.
Catch包含异常恢复的代码
finally包含资源清理的代码.保证会执行的代码
如果内部的一个catch没有捕获到异常,那么会向外层就是调用方法的那一层查找捕获的代码,总是先执行内部所有的finally语句,由内而外,最后执行Catch的语句,再执行这个Catch下边的finally.处理完之后,代码会从捕获异常的代码往下执行,不会再回到[抛出异常的代码那里往下执行了.直到找到,如果找不到就抛出未处理异常.
异常堆栈信息包含的是最新的抛出异常的起点,之前的异常信息起点会被覆盖掉.
要获得从线程起始处到异常处理之间的完整堆栈跟踪,需要使用System.Diagnostics.StackTrace表示一个堆栈跟踪,它是一个或多个堆栈帧的有序集合。
如果CLR找到了PDB文件,会包含源代码文件路径和行号等信息.
如果调用堆栈的时候发现没有调用代码中的一些方法,原因可能是:
JIT编译器内联了一些方法.避免调用方法的开销./debug命令,就是告诉编译器不要内联方法.
System.Environment.FailFast方法 在终止进程的时候不会执行任何活动的try/finally块或者finalize方法.AppDomain.Unload卸载Appdomain
2.异常处理指导原则
善用finally :lock using foreach(枚举器)都会自动加上finally语句块.
不要什么都捕捉:不要默默的Catch掉Exception类型的异常,会影响上次捕获并处理异常.可以捕获并重新抛出一个.不过是会改变异常的堆栈信息的.
得体的从异常中恢复:如果能预见到异常的类型,可以捕获该类型的异常,并继续进行处理.使程序继续运行.例如,捕获0作为除数,就给用户提示信息.
回滚操作:对已经执行的操作进行恢复回滚.
可以再捕获到的异常的Data中加入键值对的数据,重新抛出原异常.
3. 未处理的异常
CLR检测到进程中任何一个线程出现未处理的异常,就会终止进程.
应用程序发生未处理的异常时,Window会向事件日志写一条记录,:打开:”事件查看器”->Windows日志->应用程序.
还可以通过操作中心:控制面板所有控制面板项操作中心可靠性监视程序
4. 对异常进行调试
调试->异常中包含了VS能识别的不同种类的异常.
可以添加自己自定义的异常到这个表中.
引发被勾选时,表示如果发生此异常,会直接中断,而不去查找Catch语句.方便直接找到这种异常.
不够选的话,会在这个异常找不到catch语句的时候中断.默认情况下不勾选.
5. 约束执行区域(CER)
System.Runtime.CompilerServices.RuntimeHelpers.PrepareConstrainedRegions将代码体指定为受约束的执行区域 (CER).强迫trycatchfinally中的代码提前编译,提前抛出异常.
这些区域中的代码要添加属性ReliabilityContractAttribute : Attribute定义某些代码的作者和依赖于这些代码的开发人员之间的可靠性协定.
如果这些方法没有准备好,就是发生异常了,就会在执行try代码前抛出.
6.代码契约
代码契约的核心静态类是:System.Diagnostics.Contracts.Contract