/*自定义导航栏*/

【框架设计】异常

     异常

概述:在程序编译中,异常是难免不遇到的。针对异常合适的处理,可以使代码健壮性更强,便于开发维护,有利于性能提升等特点。还有以下优点:1异常处理可以将资源文件代码放在一个指定的位置。如:try{}。。finally{}块中的代码 2异常处理可以将处理的代码放在一个集中位置。如:catch{}块。有时候导致代码的异常原因有:算术溢出,堆栈溢出,内存不足,参数越界,数组索引越界,资源已释放等。 3异常处理可以定位和修复代码中的bug。当代码发生故障时,公共语言运行库遍历线程的调用堆栈,查找能够处理的代码。

 


在程序编译中,异常是难免不遇到的。针对异常合适的处理,可以使代码健壮性更强,便于开发维护,有利于性能提升等特点。还有以下优点:

1异常处理可以将资源文件代码放在一个指定的位置。如:try{}。。finally{}块中的代码

2异常处理可以将处理的代码放在一个集中位置。如:catch{}块。有时候导致代码的异常原因有:算术溢出,堆栈溢出,内存不足,参数越界,数组索引越界,资源已释放等。

3异常处理可以定位和修复代码中的bug。当代码发生故障时,公共语言运行库遍历线程的调用堆栈,查找能够处理的代码。


本文主要涉及的内容:异常处理演变,异常处理机制,符合公共语言规范(CLS)的异常和不符合公共语言规范的异常,异常的准确定义,System.Exception类,FCL中预定义的异常类,抛出异常,定义自己的异常类,如何正确的使用异常类,性能考虑,未处理异常,异常堆栈跟踪,调试异常

异常处理演变

早期的开发人员,遇到异常问题,往往通过自己编写方法,查找故障原因.这些代码量加大,也不利于检查异常.后来微软NETFremawork2.0后,引入了异常处理机制.这样简便高效解决了异常问题,加大了开发速度.不过,那时候异常只是支持公共语言规范的异常.现在的版本对是否符合CLS的异常都支持.

 

 

异常处理机制

 private void SomeMothod()         {     

        try   {   公共资源清理代码  }        

     catch (InvalidOperationException)       {       相应的异常 throw;     }     

    catch(IOException)             {       相应的异常 throw;        }          

   finally             {        公共资源清理代码,不管是否异常抛出,总会执行       }   

      }

异常处理块有三部分组成,try{}..catch{}...finally{}

try放入资源清理代码(正常需要执行代码),catch{}里面对应的异常处理。finally{}里面也是资源清理代码。整个过程由上至下运行,里面可以包含多个catch{}块。一旦try{}发生异常,则执行catch代码。有CLR搜索捕获类型与抛出异常相匹配的catch块。进入堆栈顶部,自上往下检查,一旦有相应的异常将抛出异常。如果try执行后没有发现异常,则跳过catch执行finally部分。

 

 

符合公共语言规范(CLS)的异常和不符合公共语言规范的异常,

派生自Exception的异常对象成为符合公共语言规范的异常,而非Exception则为不符合CLS异常。例如:String,Int32等

 

 

异常的准确定义,

异常不等于错误,导致抛出异常的原因:

没有足够的堆栈空间,抛出StackOverflowExceptin异常

没有找到程序集定义的类型,抛出FileNotFoundException异常。

方法的IL没有通过验证,抛出verificationException异常。

系统没有足够的内存让JIT编译IL代码,抛出OutOfMemoryException异常。

 

 

System.Exception类,System.Exception类型的公共属性:

Message,异常抛出的原因,当异常无法处理时,该消息通常写入一个日志中。

Data,键值对集合的引用,代码抛出异常前,增加一条记录。偏于查询

Source,包含产生异常程序集名称

StackTrace,导致异常跑出的所以方法名称和签名,该属性对调试很有用。

TargetSite,抛出异常的方法。

HelpLink,指向文档的URL,帮助用户理解异常。一般远程发送其他编程人员。

InnerException,当前异常抛出时,系统正在处理,该属性表示前一个异常。

 

 

FCL中预定义的异常类

异常类定义在MSCorlib.dll程序集中。(公共语言运行库)System.Exception是所以异常的基础。但是不规范CLS异常除外。(非托管语言产生的异常)

 

 

抛出异常,

计划抛出派生自Exception的是什么类型异常?

基类异常是窄而深,以为其将许多错误看着一种错误不够具体。我们需要的是宽而浅的异常机制。尽可能具体到Exception的分支。我们自己编写的异常直接继承Exception

计划为异常类型的构造器传递什么样的字符串消息?

如果铺获出异常并处理异常,那么字符串消息就不见了。但是,假如异常没有处理,该消息通常会写入日志文件。

 

 

 

定义自己的异常类,注意引用IFormattable和IComparable

 

如何正确的使用异常类,验证方法参数和正确使用finally块。

异常处理一般try。。catch。。finally。但是很多编程语言提供了构造来简化编码,例如:

C#提供lock和using语句,可以使编译器自动产生try。。finally块。下面两个例子效果一样

例一:

private void SomeMothod()
        {
            FileStream fs = new FileStream(@"C:\Data.bin",FileMode.Open);
            try
            {
                Response.Write(100/fs.ReadByte());
            }
            catch (InvalidOperationException)
            {
            }
         
            finally
            {
                fs.Close();
            }
        }

例二:

private void SomeMothod()
        {
            using (FileStream fs = new FileStream(@"C:\Data.bin", FileMode.Open))
            {
                Response.Write(100 / fs.ReadByte());
            }
           
        }

两者效果一样,后者简洁很多

还有就是使用catch (Exception e) { }尽可能不要这样做,基类是窄而深的异常机制。

 

性能考虑,

使用异常处理,减少了很多代码。其利用垃圾回收机制。大大提高开发增加安全性。相对非托管代码性能有所提升。

未处理异常,

clr向上遍历整个堆栈查找与被抛出异常匹配的catch块,如果没有匹配,就出现未处理异常,当clr检测到进程中任意线程有未处理异常,都会终止进程。

异常堆栈跟踪

System.Exception提供StackTrace属性,访问其时,实际调用clr内部代码,构建新的异常类时,StackTrace为null。他的最大一个好处是处理堆栈跟踪和构成堆栈跟踪的栈帧。

调试异常

打开vs--》调试--》异常:

 注意:该对话框支持不符合CLS异常类型

posted @ 2013-03-06 15:39  伏草惟存  阅读(690)  评论(0编辑  收藏  举报