Tom*_*m A 10 delphi exception-handling
我正在查看我们的应用程序中的一些代码,并且从我通常做的事情中发现了一些奇怪的东西.通过异常处理和清理,我们(以及其他许多程序员,我确定)使用嵌入了Try/Except块的Try/Finally块.现在我已经习惯了Try/Finally中的Try/Except,如下所示:
Try
Try
CouldCauseError(X);
Except
HandleError;
end;
Finally
FreeAndNil(x);
end;
Run Code Online (Sandbox Code Playgroud)
但是这个其他代码块是相反的:
Try
Try
CouldCauseError(X);
Finally
FreeAndNil(x);
end;
Except
HandleError;
end;
Run Code Online (Sandbox Code Playgroud)
环顾网络,我看到人们两种方式都这样做,没有解释为什么.我的问题是,哪个获取外部块并且哪个获得内部块是否重要?或者,无论结构的哪种方式,都将处理除外和最后的部分?谢谢.
一个区别是try..finally..except可能容易受到异常屏蔽情况的影响.
想象一下,在CouldCauseError()中发生异常.然后想象,企图FreeAndNIL(X)在最后导致进一步的例外.最初的异常(很可能导致导致FreeAndNIL()异常的不稳定性)丢失了.在除了处理器现在处理"下游"的例外原来后发生.
try..except ...当然可以避免这种情况,因此应该首选(处理尽可能接近其来源的例外情况).
处理诸如此类(正在清理的单个对象)的简单情况的另一种方法是在正常流程和异常处理程序中包括清理:
try
CouldCauseError(X);
FreeAndNil(x);
except
HandleError;
FreeAndNil(x);
end;
Run Code Online (Sandbox Code Playgroud)
这看起来起初有点吓人("我需要确保FreeAndNIL(X)被调用,所以我必须有一个FINALLY!"),但第一FreeAndNIL()可能不会被调用的唯一途径是,如果有是一个例外,如果是你FreeAndNIL()荷兰国际集团以及反正一个例外,它使清理的顺序一个异常清晰一点的情况下(在一定程度上必须是去除噪声的感觉"过滤"以了解正在发生的事情".
但是,我个人不喜欢它 - 如果你无论是在异常处理程序,或者你铤而走险清理行为正常的流量变化的代码,而是取决于围绕这样一个块中的代码,和块本身的大小,在还原在某些情况下,为了简化,可以认为"噪声"是合理的.
但是,这依赖于以下事实:FreeAndNIL()实际上是" NILThenFree()"... X在Free之前是NIL'd,所以如果在正常流程中FreeAndNIL(X)中发生异常,那么当异常处理程序捕获X.Free引发的异常时,X将为NIL ,因此它不会尝试"双重释放"X.
无论你决定什么,我希望有所帮助.