在堆栈跟踪中,顶部的方法调用是最近调用的方法。
当提到短语“高级处理”时,这是否意味着在方法调用者中或在catch块中调用另一个方法?
此外,在我编写的API的多层应用程序中,似乎最好的策略是始终记录异常并尽快处理它并重新抛出,以便UI中的调用方法可以显示错误。异常重新抛出是否还有其他使用场景?
如果文件被锁定,默认情况下重启操作或加载其他文件等操作是否会发生在catch块中?是关于报告错误的异常处理还是关于再次尝试操作/使用不同参数再次尝试?
由于
答案 0 :(得分:3)
更高的上升意味着堆叠更低,是的。
如果你打算改变你重试的方式 - 也就是说,你知道一种策略会起作用,或者一个策略的集合,那么ONE也许你可以在捕获中做到这一点;但是,函数或bool的错误代码可能更好;这是因为我们不实际上在讨论异常行为。
异常处理不是循环机制,不是。在例外情况下,一次又一次地重试是邪恶的。
通常您应该记录异常,但这不是异常的主要目的。 例外是他们作为从特殊行为中恢复的标准机制以良好记录(以代码方式)的方式。他们用C和C ++替换了goto和longjmp语句。如果出现问题,您可以绝对跳转到代码中的某个标签。
记录异常并重新投掷是好的,这是公认的惯例。
示例和讨论
在你的锁定示例中,你可能应该阻止等待锁释放。也许是一个自旋锁(或者等待一个短的,但是定义的间隔),如果没有释放锁,则会抛出异常 - 现在在这种情况下,这将是一个例外,因为你编写了锁定文件的代码,而你有编写代码以尽快释放锁。
这里有一个问题,你可能想要在处理异常后等待一段时间,我打赌你想假装从未发生异常 - 即重新启动你离开的地方。但异常机制无法将您带回原始阻塞发生的地方。您的解决方案是:
您可以通过再次尝试从异常(如上所述)开始新的代码回归(不是一次又一次:P)。但这是你的代码的新回归,这是不对的。
您可以跳到最初等待的位置。但是标签和跳转会让你成为大多数编程团队的贱民。我对他们并不感到不安,但那就是我。
您可以使用错误代码和防御性编程。这是最干净的方法。您的尝试只会体现您打算运行的代码,以及您的异常,这是您真正不期望的特殊行为。
代码:1
try{...}
catch{alternateStrategy()}
代码:2
try
{
IAmALabel:
checkFileLock(timeoutVal);
}
Catch
{
timeoutVal = timeoutVal*2;
goto IamALabel;
}
注意:上面可能是一个无限循环,如果你使用它就会设置一个上限。
代码3:
int tries=3;
while(true)
{
int ret=CheckFileLock(timeoutVal);
if(ret==0) // 0 = success, anything else represents a distinct error.
break;
tries--;
if(tries==0)
throw exception();
}