c# - 可以在"using"语句中为Web请求嵌入"try/catch"吗?我的代码是否正确?

Gre*_*reg 6 c# using try-catch httpwebrequest

是否可以在"using"语句中为Web请求嵌入"try/catch"?我的代码是否正确?那是我的要求是:

  1. 想要使用"using"语句来确保在任何情况下都为HttpWebResponse释放资源

    • 但是如果有异常的HttpWebResponse和"response =(HttpWebResponse)request.GetResponse();"仍然想做一些自定义的东西.特别是.

我的源代码:

        var result = new HttpHeaderInfo();
        HttpWebRequest request = null;
        HttpWebResponse response = null;
        using (response)
        {
            try
            {
                request = (HttpWebRequest)WebRequest.Create(uri);
                request.Method = "HEAD";
                request.KeepAlive = false;
                request.Timeout = Properties.Settings.Default.WebTimeoutDefault;

                response = (HttpWebResponse)request.GetResponse();
                result.LastModified = response.LastModified;
                result.ContentType = response.ContentType;
                result.StatusCode = response.StatusCode;
                result.ContentLength = response.ContentLength;
            }
            catch (Exception ex)
            {
                if (ex is InvalidOperationException ||
                    ex is ProtocolViolationException ||
                    ex is WebException)
                {
                    result.HttpError = ex;
                    result.LastModified = System.DateTime.MinValue;
                    result.ContentType = null;
                }
                else { throw; }
            }

        }
Run Code Online (Sandbox Code Playgroud)

谢谢

Aar*_*ght 10

没关系,但有点多余; 在一般意义上,您可以轻松地删除using块,在finally其后添加块catch,并Dispose在那里显式调用,这将减少代码中的嵌套.

在一个更具体的意义,有什么错误我一点是,你实际上不分配response,直到你得到里面using块,和明显的变量声明是不必要的,混乱的在这方面.我会把它重写为:

HttpHeaderInfo result;
try
{
    var request = (HttpWebRequest)WebRequest.Create(uri);
    request.Method = "HEAD";
    request.KeepAlive = false;
    request.Timeout = Properties.Settings.Default.WebTimeoutDefault;

    using (HttpWebResponse response = (HttpWebResponse)request.GetResponse())
    {
        result = new HttpHeaderInfo();
        result.LastModified = response.LastModified;
        result.ContentType = response.ContentType;
        result.StatusCode = response.StatusCode;
        result.ContentLength = response.ContentLength;
    }
}
catch (WebException ex)
{
    // etc.
}
Run Code Online (Sandbox Code Playgroud)

这比原始形式更清晰.另请注意,我正在捕捉WebException,而不是通用System.Exception.您应该捕获特定的异常类型,而不是捕获一般异常,然后检查它们的类型.


Jon*_*eet 6

其他人已经指出这是一个潜在的问题,但我想把它作为一个非常明确的问题提出来:你的使用陈述目前对你没有任何好处.

当你编写这样的using语句时:

SomeType x = value1;
using (x)
{
    x = value2;
}
Run Code Online (Sandbox Code Playgroud)

它将value1被放置在块的末尾,而不是 value2.在你的代码中,response在块内部为空; 在WebResponse你最终会不会被布置.

您应该看到关于此的警告,沿着这些方向:

警告CS0728:可能不正确地分配给本地"响应",这是使用或锁定语句的参数.Dispose调用或解锁将发生在本地的原始值上.

这个警告很重要 - 注意它.

抛开这一点,在try语句中放置一个try/catch块是完全合理的......但是在这种情况下它应该在using语句之外,让你response在适当的时候初始化变量,这样响应永远是处置.我还会考虑使用多个catch块来调用常用方法,而不是反复使用"is".