c# 异常

来源:转载

基本结构

try{}catch(other exception){///用于捕捉各种具体的异常,具体的异常会在这里对它进行马上处理}catch(exception){///这里会捕捉到除了上面的所有异常,但一般需要重新抛出异常}finally{///无论上面代码怎么样执行,最后都要执行该区域代码,用于做一些清理等动作}

规则

1、try语句至少要有一个对应的catch或finally,不允许单独一个try语句

2、如果到了调用栈顶部,仍然没有找到匹配的catch语句,就会发生未处理异常

3、找到匹配的catch块后,会先执行内层的所有finally语句,就是从抛出异常的try语句开始,到匹配异常的catch语句之间的所有finally语句。但是匹配catch语句的那个finally语句要等该catch语句执行完毕之后才能执行

4、catch语句的处理方式一般有三种

1)、向上面抛出一个相同的异常

2)、向上面抛出一个不同的异常,通常可提供更丰富的异常信息

3)、处理异常,不向上抛异常。

5、catch和finally块中的代码应该非常短,避免又出现异常。即使在catch或finally语句中抛出了异常,clr会向上抛出这个新的异常,只不过原来try语句中的异常信息就会被这个新的异常覆盖掉,一般会成为一个未处理的异常。

6、在catch语句向上抛异常,使用“throw”和“throw e”语句是有区别的,前者不会重置异常的起点,后者则会,将起点重置为throw语句这里。

7、执行catch或finally块时,clr不允许线程终止

8、在设计类库的异常时,不要自己处理异常,要抛出异常,让调用者自己去处理,如果在类库内部处理,对调用者来说就不透明,也不友好

9、禁止只捕获Exception异常而不重新抛出它,否则应用程序不知道已经出错,还会继续运行

Exception类中的常用信息字段

Message:指出抛出异常原因的文字性说明

Source:指出生成异常的程序集名称

StackTrace:包含抛出异常之前调用过的所有方法

InnerException:如果当前异常是在处理一个异常时抛出的,该属性就指向上一个异常

AppDomain FirstChanceException

这个事件是在发生异常后clr在搜索所有catch块之前发生的。因此,可利用这个事件监视AppDomain抛出的异常,添加日志记录等操作,使用原则如下

1、该事件不能处理异常,只是用于接收异常的通知

try...finally语句在某些常用的常用的操作中有省略的写法,编译器最后都会把这些省略写法还原为try...finally写法

1、lock语句,锁在finally中释放

2、using语句,在finally语句中调用Dispose方法

3、foreach语句,在finally语句中调用IEnumerator的Dispose方法

4、析构方法,在finally语句中调用Finalize方法

未处理的异常

类库开发人员压根用不着去想未处理的异常,只有应用程序的开发人员才需要关心未处理的异常,MS建议应用程序开发人员接收CLR的默认策略。也就是发生未处理异常时,windows会向事件日志写一条记录,可以再控制面板-》事件查看器-》windows日志-》应用程序中查看。

Application.ThreadException AppDomain.CurrentDomain.UnhandledException

1、前者用于捕捉ui线程的未处理异常,此时后者是捕捉不到的,并且前者也是UI线程所特有的异常,后者用于捕获非UI线程中的为处理异常

2、在前者异常中,如果没有实现该事件,则会弹出下列的界面,此时无论是点“继续”还是“退出”按钮,都不会向事件日志中写记录,点击继续按钮,程序继续,点击“退出”立即退出进程,不会也不会执行Application的ThreadExit和ApplicationExit事件

3、如果实现前者事件,并不抛出新的异常,则异常到此为止,windows也不会向事件日志中写记录

4、如果实现前者事件,并在实现程序中在再次抛出该异常,则会弹出下面的提示框,并且windows会向事件日志中写记录,同时也会执行Application的ThreadExit和ApplicationExit事件

 

Application.ApplicationExit Application.ThreadExit异常处理的关系

1、如果是正常结束程序,或者用任务管理器强制关闭程序都会触发这两个事件

2、但是如果没有实现未处理异常的事件,并弹出的未处理提示框中点退出按钮,则不会执行这两个事件,很奇怪

分享给朋友:
您可能感兴趣的文章:
随机阅读: