c# - 可以嵌入“try/catch”吗?在“使用”中网络请求的声明?我的代码正确吗?

发布于 2024-08-20 00:10:14 字数 1494 浏览 9 评论 0原文

是否可以在 Web 请求的“using”语句中嵌入“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; }
            }

        }

谢谢

Is it ok to embed a "try/catch" within a "using" statement for a web request? Is my code correct? That is my requirements are:

  1. Want to use the "using" statement to make sure resources are released in any case for HttpWebResponse

    • But still want to do some custom stuff if there is an exception re HttpWebResponse and "response = (HttpWebResponse)request.GetResponse();" in particular.

My source code:

        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; }
            }

        }

thanks

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

一袭白衣梦中忆 2024-08-27 00:10:14

还可以,但是有点多余;一般来说,您可以轻松删除 using 块,在 catch 之后添加 finally 块,并显式调用 Dispose< /code> 在那里,这会减少代码中的嵌套。

从更具体的意义上来说,让我有点烦恼的是,在进入 using内部之前,您实际上并没有分配response,并且在这种情况下,显式变量声明是不必要的并且令人困惑。我将其重写为:

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.
}

这比原始形式清晰得多。另请注意,我捕获的是 WebException,而不是通用的 System.Exception。您应该捕获特定的异常类型,而不是捕获通用异常然后检查其类型。

It is OK, but a little redundant; in a general sense, you could easily remove the using block, add a finally block after the catch, and explicitly call Dispose in there, which would reduce the nesting in your code.

In a more specific sense, what bugs me a little is that you don't actually assign response until you get inside the using block, and the explicit variable declarations are unnecessary and confusing in this context. I would rewrite it as:

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.
}

This is a lot clearer than the original form. Also note that I'm catching WebException, not the generic System.Exception. You should catch specific exception types instead of catching generic exceptions and then checking their type.

水晶透心 2024-08-27 00:10:14

其他人指出这是一个潜在问题,但我想将其作为一个非常明确问题提出:您的 using 语句目前对您没有任何好处。

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

SomeType x = value1;
using (x)
{
    x = value2;
}

value1 将被处理在块的末尾,而不是 value2。在您的代码中,response 在块内之前为 null;您最终得到的 WebResponse不会被处理。

您应该会看到有关此问题的警告,大致如下:

警告CS0728:
本地分配可能不正确
‘回应’
是 using 或 lock 语句的参数。 Dispose 调用或
解锁将发生在本地的原始值上。

这个警告很重要——请注意。

抛开这一点,将 try/catch 块放在 using 语句中是完全合理的...但在这种情况下,它可能应该位于 using 语句之外,让您初始化响应< /code> 在适当的时间变量,以便响应始终被处理。我还会考虑使用多个 catch 块调用一个通用方法,而不是重复使用“is”。

Others have pointed this out as a potential problem, but I want to raise it as a very definite problem: your using statement is doing you no good at all at the moment.

When you write a using statement like this:

SomeType x = value1;
using (x)
{
    x = value2;
}

it is value1 which will be disposed at the end of the block, not value2. In your code, response is null until inside the block; the WebResponse you end up with will not be disposed.

You should be seeing a warning about this, along these lines:

warning CS0728:
Possibly incorrect assignment to local
'response' which
is the argument to a using or lock statement. The Dispose call or
unlocking will happen on the original value of the local.

That warning is important - heed it.

Leaving that aside, it's entirely reasonable to put a try/catch block in a using statement... but in this case it should probably be outside the using statement, letting you initialize the response variable at the appropriate time so that the response will always be disposed. I would also consider using multiple catch blocks calling a common method rather than using "is" repeatedly.

橘亓 2024-08-27 00:10:14

这完全没问题。您处理异常并且不希望它进一步冒泡,这很好,嵌套的 try/catch/finally 块也没有问题。 (在内部,像这样的“使用”只是一次尝试/最后。)

更新:仔细阅读一下,我认为您实际上希望在“尝试”块内使用 - 您实际将对象放入“响应”中的行' 变量是您希望 'using' 块开始的位置。它实际上按原样编译吗?

This is totally OK. You handle the exception and don't want it bubbling up further, that's just fine, and nested try/catch/finally blocks are no problem. (Internally a 'using' like this is just a try/finally.)

UPDATE: read a little closer, and I think you actually want the using inside the 'try' block - the line where you actually put an object in the 'response' variable is where you want the 'using' block to begin. Does it actually compile as-is?

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文