当在finally块中可能引发异常时,如何传播这两个异常-从catch到from finally?

作为一种可能的解决方案-使用AggregateException:

internal class MyClass
{
    public void Do()
    {
        Exception exception = null;
        try
        {
            //example of an error occured in main logic
            throw new InvalidOperationException();
        }
        catch (Exception e)
        {
            exception = e;
            throw;
        }
        finally
        {
            try
            {
                //example of an error occured in finally
                throw new AccessViolationException();
            }
            catch (Exception e)
            {
                if (exception != null)
                    throw new AggregateException(exception, e);
                throw;
            }
        }
    }
}

这些异常可以像下面的代码片段一样进行处理:
private static void Main(string[] args)
{
    try
    {
        new MyClass().Do();
    }
    catch (AggregateException e)
    {
        foreach (var innerException in e.InnerExceptions)
            Console.Out.WriteLine("---- Error: {0}", innerException);
    }
    catch (Exception e)
    {
        Console.Out.WriteLine("---- Error: {0}", e);
    }

    Console.ReadKey();
}

最佳答案

正如评论所建议的那样,这可能表示“不幸的”结构化代码。例如,如果您发现自己经常遇到这种情况,则可能表明您尝试在方法中做太多事情。您只想在没有其他事情可以做的情况下抛出异常(您的代码被“卡住”了无法编程的问题。您只想在有合理期望的情况下捕获异常) 。框架中有一个OutOfMemoryException,但是您很少会看到有人试图捕获它,因为在大多数情况下,这意味着您很无聊:-)

如果finally块中的异常是try块中异常的直接结果,则返回该异常只会使实际问题变得复杂或模糊,从而使解决起来更加困难。在极少数情况下,如果有返回原因的有效原因(例如异常),则可以使用AggregateException。但是在采用这种方法之前,请先问问自己是否有可能将异常分离为可以返回(单独)并处理单个异常的单独方法。

10-07 19:47
查看更多