您的位置:首页技术开发.Net 专栏 → 详解.NET 4.0异常处理功能

详解.NET 4.0异常处理功能

时间:2010/1/9 14:00:00来源:本站整理作者:我要评论(0)

为什么需要Corrupted State Exceptions

  异常有大有小,小的如字符串为空,这些一般是用户输入问题,它不会引起整个程序或者系统中相关进程出现崩溃的情况;大的如访问冲突异常,这可能是你的程序在做一些可能会引起操作系统崩溃的事情,这种异常一般都比较严重,一般如果出现这种异常,通常程序应该做的是结束当前进程,然后老老实实向用户报告你犯傻了并提示他重启程序。不过在.NET 4.0以前,CLR是很相信程序员不会搞出一些诸如catch(Exception e){return;}这种不负责任的代码的,因此它不分轻重缓急,只要是异常,它统统都会抛出来,这里面不仅仅有托管代码的异常,也有一些.NET程序员不太好看懂的COM和WIN32异常。

  CLR相信程序员在捕获异常的时候会只处理他们清楚的异常,但很多时候,作为开发人员,由于上面有老板,下面有客户,我们真的很难做人,想想如果老板动不动就听又客户抱怨他们只不过点了两下按钮程序就报错然后结束了,他还能给你加薪么?虽然很多时候我们清楚我们的代码不会出问题,但我们很难保证天时地利人和样样俱全,为了给老板和客户一个交代,这时候很多人都会选择去捕获所有的异常,然后记录下异常信息,然后程序继续彪悍的跑下去。

  看似一些都很完美,客户不会再像以前那么频繁的抱怨程序down掉,老板也就高兴了。但有人不高兴。小的未知异常当然不会捅大的篓子,但对有些可能导致程序甚至操作系统崩溃的异常如果不中断程序的话可能影响的就是一大片了。这个时候客户可能不会抱怨你,但他会抱怨微软出了个烂操作系统,一天到晚蓝屏,或者他会抱怨微软的Office或者IE太烂,他只不过加载了一个插件,结果整个Outlook就报错崩掉了。你是省事了,但微软得来被黑锅,而且他还不知道这个黑锅里面到底是咋回事。

  当然上面是玩笑,不过不管怎样,从程序安全和稳定的角度来看catch(Exception e)确实不是一个好的编程习惯,然而木已成舟,既然无法避免程序员偷懒,微软只能采取一些补救措施了,这里他们在CLR 4中添加了新的异常处理机制,自4.0以后,CLR不会主动给你抛出所有异常了,对于那些它认为是危险的,可能导致进程崩溃的异常它会标记为Corrupted State Exception并自己处理掉而不是抛给程序员来做,如AccessViolationException这种继承自SystemException的异常就会被当做Corrupted State Exception来处理。不过这里要注意的是,仅仅异常类型是可能会危险级别的异常还不够,CLR还会判断抛出异常的所有者,如果它发现是由操作系统抛出的访问冲突则会认为这是状态崩溃异常,但如果异常是由用户代码抛出,则CLR不会对其做特殊处理,它仍然会像以前一样将其正常抛出。

  如何继续捕获Corrupted State Exceptions

  那么CLR包了这块的异常处理是不是意味着以后我们程序员就没得选只能老老实实向用户报告我们的产品不行,然后让老板炒我们鱿鱼了呢?那些.NET 4.0以前发布的,处处是漏洞的产品我们怎么处理?

  虽然微软不再那么相信程序员是负责人的人,但它也做那么绝。虽然默认.NET 4.0以后CLR会处理这些异常,程序员也不用再操心这些危险的异常了。但你仍然可以继续你以往敷衍上司的做法。并且微软还提供了两种方式。

  首先对于以往的程序,微软提供了两种选择:

  1. 如果你想把以往旧的代码在.NET Framework 4.0下编译但又不想改代码的话,你可以在你的程序的配置文件中添加一个新的节点:legacyCorruptedState­­ExceptionsPolicy=true,它使得你的代码仍能按照以前处理异常的方式来继续运行。

  2. 如果你不想有任何改变,直接把以前已经编译好的程序在.NET Framework 4.0下运行则不需要任何改变,CLR会保证所有的异常仍然按照以往的方式处理。

  其次,对于那些使用了.NET Framework 4.0 但又想自己处理这些导致程序状态崩溃的异常,微软同样提供了选择,他们在.NET 4.0中增加了一个新的命名空间:System.Runtime.ExceptionServices,这里面有个特性类叫做HandleProcessCorruptedStateExceptionsAttribute,你只需要在相应方法上添加这个属性,CLR就会把所有的异常处理交给你做,就像以前一样。e.g.

  view sourceprint?01 // This program runs as part of an automated test system so you need

  
// to prevent the normal Unhandled Exception behavior (Watson dialog).

  
// Instead, print out any exceptions and exit with an error code.

  [HandledProcessCorruptedStateExceptions]

  
public static int Main()

  {

  
try

  {
// Catch any exceptions leaking out of the program

  CallMainProgramLoop();

  }

  
catch (Exception e) // We could be catching anything here

  {
// The exception we caught could have been a program error

  
// or something much more serious. Regardless, we know that

  
// something is not right. We'll just output the exception

  
// and exit with an error. We won't try to do any work when

  
// the program or process is in an unknown state!

  System.Console.WriteLine(e.Message);

  
return 1;

  }

  
return 0;

  }

 

  当然要注意的是这个特性只能应用在方法上。

  总结

  异常处理常常是程序员心中的一块心病,尽管微软认为自己得为纵容程序员滥用异常捕获负责然后添加了这个新的异常处理机制,不过在他们看来,那种catch(Exception e)的行为仍然是不对的。他们认为异常的出现表明当前程序的状态出现了问题,而程序员应当清楚这些错误的状态所造成的后果,所以程序员应当捕获具体的异常并作出正确的处理,而不是因为偷懒或者省事去简单处理所有异常。

相关视频

    没有数据

相关阅读 vs.netIDE报"以下文件中的行尾不一致,要将行尾标准化吗?"的解决ie6下面asp.net mvc3 部署应用程序.NET 3.5 安装错误的四个原因及解决方法支持无限制历史记录的Paint.NET 3.5.8 Final,你用了吗?.NET Framework环境安装错误怎么办?JVM和.NET CLR和哪个会被彻底击败在asp.net mvc中实现右键菜单和简单的分页教程VB.NET如何得到调用当前过程的方法名称和类名称

文章评论
发表评论

热门文章 没有查询到任何记录。

最新文章 什么是.NET中的TDD?ASP.NET AJAX入门简介 WebMatrix入门教程VC++2008中如何调用GetOpenFileName打开文件PlaySound函数在VC++6.0中如何播放音乐及声请问VC++回调函数怎么用

人气排行 嵌入式实时操作系统VxWorks入门教程ArrayList 与 string、string[] 的转换C#遍历整个文件夹及子目录的文件代码WebMatrix入门教程asp.net判断文件或文件夹是否存在c#判断数据NULL值的方法vc++6.0怎么写Windows简单窗口代码.net解决数据导出excel时的格式问题