最近我参加了Jeffrey Richter关于.NET的培训课程.他提到了一种编码"死亡很棒"的策略.也就是说,即使在程序或事件循环的根目录下也不要写"catch(Exception ex)".如果抛出一些未处理的异常,只需让进程死掉.
我不确定这是对的.就个人而言,我更喜欢用" try {...} catch(Exception ex) {log and try to recover}
"来包装在最高级别的执行中.实际上,如果从asXx抛出任何异常,ASP.NET不会死亡.如果它因异常而死亡,那么一个银弹请求可能会使整个服务无效.
你怎么看?
我认为这取决于您运行的应用程序类型以及"垂死"的后果.对于许多客户端应用程序,死亡是很棒的.对于服务器,通常不是那么多(并且吞咽和日志是合适的).没有一个通用的解决方案.
也称为进攻性编程.
你应该看看," 进攻性编程:早期崩溃,经常崩溃 ".
这与防御性规划的规范有着截然不同的意识形态:
[防御性编程]旨在确保软件的持续功能,尽管不可预见地使用所述软件.
我个人喜欢"早期崩溃,经常崩溃"的理念.
我见过太多了:
try { // ... Huge block of code goes here } catch(Exception ex) { // Do nothing... }
这比崩溃还要糟糕得多.如果处理异常,那么一点点防御性编程就可以了.
这一切都取决于你如何处理异常.如果只在发生真正异常的事件时抛出异常(而不是在数据库查询没有返回结果或者格式不正确时),那么你真的不需要捕获异常.因为您的程序无法恢复,所以您可以从中恢复的任何内容都不是例外,而是一个错误.
听起来像Guruspeak
这听起来像是大师们宣传的另一个一般指导原则,这本身并不是一个糟糕的建议.但是,该指南可以很容易地应用于不属于它的地方.我认为记住你上面使用的关键词是"一种编码策略",因为这种策略在某些领域非常有用,但在其他领域却非常有害.
死亡是真棒-如果你有很多的紧耦合组件的状态取决于对方的,那么一个异常很容易被一个灾难性的事件.但是,您的目标之一应该是以一种单一故障不必降低整个系统的方式进行编码(通知目标).
您如何看待以下应用程序在普通例外情况下死亡:
医疗设备
发电厂
入侵检测系统
对于你在try/catch中捕获的异常 - 你真的应该期待它们并处理它们.对于所有其他情况,最好快速失败到预测的运行级别.那么,如果你在网络或网络处理程序,为什么不让当前的操作死?你真的需要整个应用程序吗?
如果您正在开发一个关键任务且具有公共界面的应用程序,这将变得越来越重要.如果有可用的例外可能会导致应用程序崩溃,那么这将成为黑帽黑客意图导致拒绝服务攻击的攻击媒介.
滥用这种策略的边缘情况有点太大,不值得赞扬.更好的方法是解决您的域名问题.了解此状态正在发生什么,并将适当的部分应用于您的问题.
注意事项:我在服务器端系统上工作,正常运行时间和安全性至关重要.
编辑:我想我对"过程死"的含义感到困惑 - 这是对整个应用程序的引用还是仅仅是正在运行的线程等?
Karl Seguin说以下关于异常处理:
只处理您可以实际执行某些操作的异常
你无法对绝大多数异常做任何事情
这个主题的介绍很好.
这是非常微软的.
MS希望您将所有未处理的异常抛给WER.(Windows错误报告,当应用程序崩溃时,您将错误发送到Microsoft的对话框)
这样您就可以获得使用指标,并可以专注于导致客户悲痛的关键未处理异常.我相信这个想法会迫使你去思考例外的来源.
但我全心全意地同意你的看法.即使你重新抛出之后,你总是会在根处捕获未处理的,记录发生的事情.唯一的问题是如果你的未处理的ex是内存不足,在这种情况下你的日志调用可能会失败,因为JIT不能分配更多的内存等.我认为C++程序通过占用内存泡来解决这个问题,在未处理的异常上释放它,然后运行一个非常紧密的日志例程,尝试并优雅地失败.