昨天我参加了关于SO专门讨论OutOfMemoryException以及处理它的优缺点的讨论(C#try {} catch {}).
我处理它的专业人士是:
但并非所有人都同意这一点,并推测在此异常之后未知的程序状态以及无法做一些有用的事情,因为它需要更多的内存.
因此我的问题是:没有处理OutOfMemoryException并在发生时立即放弃的严重原因是什么?
编辑:你认为OOME和ExecutionEngineException一样致命吗?
免责声明,我来自Java背景.我没有做太多的C#.这两个世界之间存在大量的转移,但当然存在差异,其中一个是异常倾向于被考虑的方式.
我最近回答了一个C#问题,建议在某些情况下,这样做是合理的:
try {
some work
} catch (Exeption e) {
commonExceptionHandler();
}
Run Code Online (Sandbox Code Playgroud)
(原因不重要).我收到的答复我不太明白:
直到.NET 4.0,捕获异常非常糟糕.这意味着你可以捕获各种低级致命错误,从而掩盖错误.它还意味着如果某种类型的损坏触发了这样的异常,堆栈上的任何打开的finally块都将被执行,所以即使callExceptionReporter函数尝试记录并退出,它甚至可能无法到达那一点( finally块可能再次抛出,或导致更多损坏,或从磁盘或数据库中删除重要的东西).
我可能比我意识到的更困惑,但我不同意其中的一些.请其他人评论.
我知道有很多低级别的例外我们不想接受.我的commonExceptionHandler()函数可以合理地重新抛出那些.这似乎与对相关问题的答案一致.这说"根据你的上下文,使用catch(...)是可以接受的,只要重新抛出异常即可." 所以我总结使用catch(Exception)并不总是邪恶,默默地吞下某些例外.
短语"在.NET 4之前它对Catch Exception来说非常糟糕".NET 4中有哪些变化?这是对AggregateException的引用,它可能会给我们一些与我们捕获的异常有关的新事物,但我不认为更改是基本的"不要吞下"规则.
下一句话真的很麻烦.这可能是对的吗?
它还意味着如果某种类型的损坏触发了这样的异常,堆栈上的任何打开的finally块都将被执行(finally块可能再次抛出,或导致更多损坏,或从磁盘或数据库中删除重要的东西)
我的理解是,如果有一些低级代码
lowLevelMethod() {
try {
lowestLevelMethod();
} finally {
some really important stuff
}
}
Run Code Online (Sandbox Code Playgroud)
在我的代码中我调用lowLevel();
try {
lowLevel()
} catch (Exception e) {
exception handling and maybe rethrowing
}
Run Code Online (Sandbox Code Playgroud)
无论我是否捕获异常,这对于finally块的执行都没有任何影响.当我们离开lowLevelMethod()时,finally已经运行了.如果最终要做任何坏事,比如我的磁盘损坏,那么它会这样做.我捕捉异常没有任何区别.如果它到达我的异常块我需要做正确的事情,但我不能成为dmis执行最终的原因
我应该在try中放入多个语句然后捕获所有可能的异常,还是应该只在try语句中放入一个语句?
例:
try {
MaybeThrowIOException();
MaybeThrowFooBarException();
return true;
} catch (IOException e) {
// ...
} catch (FooBarException e) {
// ...
}
Run Code Online (Sandbox Code Playgroud)
要么
try {
MaybeThrowIOException();
} catch (IOException e) {
// ...
}
try {
MaybeThrowFooBarException();
} catch (FooBarException e) {
// ...
}
return true;
Run Code Online (Sandbox Code Playgroud)