在某些情况下,如何处理类似以下类的所有异常?
class Test : IDisposable {
public Test() {
throw new Exception("Exception in ctor");
}
public void Dispose() {
throw new Exception("Exception in Dispose()");
}
~Test() {
this.Dispose();
}
}我试过了,但不起作用:
static void Main() {
Test t = null;
try {
t = new Test();
}
catch (Exception ex) {
Console.Error.WriteLine(ex.Message);
}
// t is still null
}我也尝试使用"using“,但它不能处理~Test()抛出的异常;
static void Main() {
try {
using (Test t = new Test()) { }
}
catch (Exception ex) {
Console.Error.WriteLine(ex.Message);
}
}有什么想法吗?我该怎么做?
发布于 2010-04-20 09:24:13
首先,终结器应该永远不会抛出异常()。如果是这样的话,一定是出了灾难性的问题,应用程序应该会严重崩溃。终结器也不应该直接调用Dispose()。终结器仅用于释放非托管资源,因为一旦终结器运行,托管资源甚至可能不处于有效状态。托管引用已经被垃圾回收器清除,因此您只需要在Dispose中处理它们,而不是在Finalizer中。
也就是说,如果显式调用Dispose,则应捕获Dispose中的异常。我不能很好地理解“使用”的情况是如何没有抛出异常的。也就是说,如果你能避免的话,Dispose也不应该抛出异常。特别是,在using块之后抛出异常的Dispose将用Dispose异常“覆盖”using块内可能发生的任何异常。
一些额外的参考材料here
发布于 2010-04-20 09:30:29
我认为部分答案是你不应该在这些情况下处理异常。
只有在可以从异常中恢复,或者可以向异常添加附加信息并重新引发时,才应该捕获异常。您不应该捕获每个异常。让调用堆栈中较高层的代码处理尽可能多的异常。
发布于 2010-04-20 10:35:02
我有几点看法。
首先,避免从Dispose抛出异常。事实上,我几乎可以说永远不会。.NET开发人员已经习惯于期望Dispose总是成功,这是有充分理由的。每次都将调用包装在try-catch中会很笨拙,而且肯定会降低可读性。
其次,这是一个经常争论的问题,避免从构造函数中抛出异常。但是,像SqlException这样不可预测的异常会迫使调用者将构造函数包装在try-catch块中。再一次,这导致了笨拙的编码场景。没有实例引用,调用方无法调用Dispose。
https://stackoverflow.com/questions/2671948
复制相似问题