【问题标题】:Close HttpWebRequest to free up resources关闭 HttpWebRequest 以释放资源
【发布时间】:2015-06-21 13:02:25
【问题描述】:

我在 c# 中创建 HTTP WebRequests 来浏览网站。我创建请求,获得响应并将其读入 StreamReader。然后我使用相同的请求变量来创建一个新的请求并获得一个新的响应......

下面是我的代码:

HttpWebRequest request;
WebResponse response;
Stream responseStream;
StreamReader reader;
string responseFromServer;

request = (HttpWebRequest)WebRequest.Create("https://www.firstRequest.com");

//set cookies and headers here... 

response = request.GetResponse();

responseStream = response.GetResponseStream();
reader = new StreamReader(responseStream);
responseFromServer = reader.ReadToEnd();


//second request using the same variables
request = (HttpWebRequest)WebRequest.Create("https://www.secondRequest.com");
response = request.GetResponse();

responseStream = response.GetResponseStream();
reader = new StreamReader(responseStream);
responseFromServer = reader.ReadToEnd();

我知道我必须关闭响应、流和流读取器以释放资源。 我必须在每个请求之间还是在所有事情结束时都这样做?

【问题讨论】:

    标签: c# stream httpwebrequest


    【解决方案1】:

    是的,您每次都需要自己清理。只需使用您忽略的 IDisposable 功能:

    所以,你可以

    using(response = request.GetResponse())
    {
        using(responseStream = response.GetResponseStream())
        {
            using(reader = new StreamReader(responseStream))
            {
                responseFromServer = reader.ReadToEnd();
            }
        }
    }
    

    或更简洁:

    using(response = request.GetResponse())
    using(responseStream = response.GetResponseStream())
    using(reader = new StreamReader(responseStream))
    {
        responseFromServer = reader.ReadToEnd();
    }
    

    ...现在您无需担心致电Close。 IDisposable 实现会为您处理它(当using 块结束时)。

    【讨论】:

    • 那么在你的 using 语句之间我应该从哪里取出需要进入的代码呢?
    • 当然。你说使用,使用,使用,然后是你的代码块。我可以参考代码块中的响应 - 还是它已经关闭。我不明白你写代码的方式。谢谢
    • 所以我修改了我的代码,希望它更能自我解释。是的,您可以在其 using 块中引用响应。块结束后,Dispose 将在“已使用”项上自动调用。调用 Dispose 和 Close 是等效的,因此这可以满足您的要求。一旦调用 dispose,继续使用已处理的项目通常是不安全的。不过,为变量分配新的响应是安全的。
    【解决方案2】:

    当他说你应该使用 using 指令时,Alltough @spender 有一个观点,我认为他的回答不能回答你的问题或特别有帮助。

    在考虑此类问题时,请考虑 C# 的基本原理以及实现 IDisposable 的对象。这样做的类使用了在不再使用类时需要释放的非托管资源。这发生在 using 块的末尾或调用 Dispose 时。

    然而,在调用Dispose 之后,该对象不应再被使用。这是与Close 的根本区别。使用Close 响应释放资源,并且同一对象可以被另一个请求重用。 MSDN for Close

    现在让我们考虑一下如果简单地覆盖响应变量会发生什么。类是 C# 中的引用类型,该变量现在将引用一个新对象,而旧的响应对象将在涅槃中消失,等待最终由 GC 收集,而不会调用 Dispose。当然不是你想要的。

    所以如果你想重用变量,请确保你使用Close

    【讨论】:

    • 我必须关闭哪些?响应,流式阅读器和阅读器?不要求 - 对吧?两次关闭同一个资源会不会很痛苦?我在一个循环中调用了 close ,然后当它跳出循环时,我想再次调用 close 来表示肯定。可以吗?
    • 请求没有实现IDisposable,所以那里没有什么可以关闭的。其他一切都应该正确关闭。当然,如果您每次都使用Close,您可以在循环中重用该变量。根据循环运行的频率,您可能需要考虑更有效的替代方案。只需确保在变量被覆盖或不再使用之前调用 Close。这通常可以通过良好的循环设计轻松实现。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-07-08
    • 2015-03-15
    • 2014-01-14
    • 2018-12-08
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多