使用块吞咽异常

时间:2011-06-23 17:11:25

标签: c# exception-handling using-statement

我有

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块内的逻辑抛出异常,这就是我在一个常见位置处理的问题。

谢谢,

3 个答案:

答案 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