关于try catch:C#“using”块和捕获异常

C# “using” blocks and catching exceptions

本问题已经有最佳答案,请猛点这里访问。

我有这个代码:

1
2
3
4
5
using (var requestStream = request.GetRequestStream())
{
    byte[] data = Encoding.UTF8.GetBytes(xmlData);
    requestStream.Write(data, 0, data.Length);
}

如果由于远程服务器关闭而导致我的请求失败,我该如何捕获错误?

我应该扩展using块来尝试最后捕获吗,还是在使用"using"块时有一种更优雅的方法可以做到这一点?

(我只需要通过这种方式捕获服务器故障类型的错误-我需要向客户机显示这些错误的发生是因为他们的服务器连接不充分,而不是因为我们的软件中的错误或其他原因)。


这里肯定有四种选择:

  • 放弃using,只要有一个try/catch/finally

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    var requestStream = request.GetRequestStream();
    try
    {
        byte[] data = Encoding.UTF8.GetBytes(xmlData);
        requestStream.Write(data, 0, data.Length);
    }
    catch (IOException e) // Or whatever
    {
        // Whatever you want
    }
    finally
    {
        requestStream.Dispose();
    }
  • using块内只放一个try/catch块:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    using (var requestStream = request.GetRequestStream())
    {
        try
        {
            byte[] data = Encoding.UTF8.GetBytes(xmlData);
            requestStream.Write(data, 0, data.Length);
        }
        catch (IOException e) // Or whatever
        {
            // Whatever you want
        }
    }
  • 与第二个选项相同,但在trycatch块外而不是在using块内。老实说,我认为你用它没什么区别。

  • 无论如何,在更高的级别捕获异常,例如在调用方法中。通常这是一种更好的方法,因为您可能希望从"大"操作的角度,以相同的方式处理多个"小"操作中的一种异常。

我个人一般赞成第二种方法或第四种方法。这是一个始终如一的变化:当我想要捕获一个异常时,我引入了一个try/catch块。事实上,它恰好在using语句中,既不在这里,也不在那里。最后会有更多的筑巢,但我发现这种情况很少发生,这不是问题。


如果初始化失败,using语句仍将抛出异常,因此您可以将其包装在自己的try/catch块中。