结构化异常处理不好吗?什么是处理异常的正确方法?异常处理
编辑:在.NET中使用C#的异常处理。
我通常有一组特定的异常类(DivideByZeroException,ArrayTypeMismatchException)并且没有泛型“catch(Exception ex)”。
这个背后的思想是,我期望发生某些类型的异常,并在发生异常时定义特定的操作,并且意外的异常会升起界面(无论是Windows还是Web)。这是一个很好的做法吗?
结构化异常处理不好吗?什么是处理异常的正确方法?异常处理
编辑:在.NET中使用C#的异常处理。
我通常有一组特定的异常类(DivideByZeroException,ArrayTypeMismatchException)并且没有泛型“catch(Exception ex)”。
这个背后的思想是,我期望发生某些类型的异常,并在发生异常时定义特定的操作,并且意外的异常会升起界面(无论是Windows还是Web)。这是一个很好的做法吗?
捕获语句+堆栈跟踪。在没有打印堆栈跟踪的情况下,如果没有捕获到异常,您或其他人将不得不再次检出该代码,并在发生错误并且日志文件为空或模糊时在Catch块中放置堆栈跟踪。
我不确定'结构化异常处理'是什么意思。
在异常处理中可以做的最糟糕的事情是“吞下”异常或者静静地处理异常。
不这样做:
try {
...
}
catch (Exception e) {
//TODO: handle this later
}
这是很经常做出于懒惰让代码编译。如果您不知道如何处理特定级别的异常,请让该方法抛出异常,并且至少在顶部有一个catch all handler。以某种方式提供反馈(通过GUI,页面/电子邮件发送给支持人员,日志文件),以便问题最终得到解决。默默地捕捉异常几乎总是会导致稍后发生更大的问题,并且难以追踪。
我的建议:
不要捕捉异常,除非:
捕获在尽可能高的水平异常意味着你得到最大的调用堆栈,当你经历的日志,并想看看初始动作触发的序列,这是非常有用的首先导致例外的事件。
这是一个复杂的话题......有这方面的书......但......有两种主要的异常处理类型......内联,其中处理潜在错误的代码与方法或例程将“正常”执行的代码以及结构化异常处理(其中代码位于其他地方)以及基础结构被设计为自动处理该异常处理代码意外事件(错误)发生......两者都有优势和劣势。 “内联”方法倾向于产生更加混乱的代码(带有错误代码),难以阅读和维护。但是,由于它不需要任何前期分析,所以它更容易生成。使用内联错误处理时,您经常会看到方法返回布尔值或数字“错误”代码,向调用方指明metjhod或例程是否成功。这消除了使例程“返回”有意义的业务价值或对象的“功能”语法(因为按惯例每个函数都必须返回错误代码)。使用结构化异常处理时,此问题没有实际意义。
结构化异常处理otoh通常很难做好,因为它需要事先分析例程或方法可能产生的错误以及该方法可以或应该对每个错误执行什么操作if它确实发生。
有一两件事是肯定的,不要在单一成分的两种方法混合...
我不是一个Windows程序员,但在使用结构化异常处理处理硬件异常之类的软件在我看来,例外意味着:
所以问题要问,IMO,主要有:
如果答案为'是','是','否',则需要结构化的异常处理。否则,你可能可以避免它,在这种情况下,你可能想要。编写异常安全的代码非常棘手,所以异常保证越强大,你越能提供更好的结果。可能与SEH划分为零的代码不提供不保证,或许在重新设计时可能会导致呼叫者不提供数据,但可以这样做。但是如果一个函数由于其他原因而必须抛出异常,那么也可能将它们丢给硬件陷阱,这可能会让事情变得更糟。
一个值得注意的特例是内存分配。不确定.NET是否这样做,但是如果分配的虚拟地址空间不足,则Linux分配只会失败。物理内存在第一次使用时被提交,如果没有足够的硬件,会导致硬件异常。由于内存分配是假定在发生故障时抛出std :: bad_alloc,并且实现未能实现此标准的这一要求,所以可能是是因为在某些情况下将硬件异常转换为软件是正确的。但是,这种硬件异常可能会发生在意想不到的地方(包括您认为不太合适的例程),所以仍然可能无法妥善处理,这就是为什么linux核心转储而不是抛出。在实践中,完全初始化的任何东西都会导致其构造函数崩溃,这通常足够接近分配,而软件异常会变得有用。
“结构化”是什么意思? – 2008-12-09 14:33:03
如果你提到了一种语言,这将是一件好事,所以我们可以在详细和更好的情况下帮助你。 – GEOCHET 2008-12-09 14:33:06