我有
void foo1()
{
using(...){...}
}
void foo2()
{
using(...){...}
}
void foo3()
{
using(...){...}
}
我有
void foo()
{
...
backgroundWorker.DoWork += (s, ev) =>
{
try
{
foo1();
foo2();
foo3();
}
catch (Exception ex)
{
// log ex
}
};
...
}
我刚看到using
阻止吞下异常。它有一种优雅的方式来处理foo1()
中foo2()
,foo3()
和foo()
的例外情况。我不希望在方法中的每个using
块中都有try / catch。我偶然发现this post建议使用扩展方法,但我只是检查是否有更好的方法。
仅供参考,网络断开会导致using
块内的逻辑抛出异常,这就是我在一个常见位置处理的问题。
谢谢,
答案 0 :(得分:3)
我想我理解这种困惑。这里有一些伪代码(它可能实际执行?)更简单地解释你的场景:
public class Foo
{
public void DoStuff()
{
using (var x = new Thing())
{
throw new ApplicationException("This code breaks");
}
}
private class Thing : IDisposable
{
public override Dispose()
{
throw new ApplicationException("Help, I can't dispose!");
}
}
}
此代码可以被认为与此代码相同:
public class Foo
{
public void DoStuff()
{
var x = new Thing();
try
{
throw new ApplicationException("This code breaks");
x.Dispose();
}
catch (Exception err)
{
x.Dispose();
rethrow;
}
}
private class Thing : IDisposable
{
public override Dispose()
{
throw new ApplicationException("Help, I can't dispose!");
}
}
}
通过使用using
块,您基本上是在说,“无论您做什么,请在继续之前对此对象执行Dispose()
。”但是,当using
失败时,Dispose()
块无法正常处理该情况。因此,它永远不会抛出内部异常,因为还有另一个异常会抢占它,即使它之后发生了。
这有意义吗?我甚至回答了你的问题吗?我不确定你是否正在寻求帮助理解这个或什么。
答案 1 :(得分:1)
我担心的是,微软和WCF一样,在这里陷入了同样的兔子洞。
请参阅Avoiding Problems with the Using Statement。
也许他们应该遵循自己的guidelines。
在几乎所有(其他)案例中,using
块都是最佳做法。
答案 2 :(得分:0)
您可以尝试使用此语句来起泡和使用语句
中的异常Exception exc = null;
using (var x = new object())
{
try
{
// do something x, that causes an exception to be thrown
}
catch(Exception ex) { exc = ex; } // bubble-up the exception
}
if(exc != null) { throw exc; } // throw the exception if it is not null