WebException.Response.GetResponseStream()应该关闭/处理吗?

时间:2015-10-01 15:40:13

标签: c# .net idisposable httpwebresponse webexception

当我抓住.NET WebException时,我应该关闭/处置Response.GetResponseStream()吗?

MSDN example不会关闭或处置异常中的任何内容。

许多SO answers建议处理响应和/或流。

我处理了流,这造成了很大的问题。因为GetResponseStream()(总是?/有时?)返回相同的实例。因此,当我获得响应流然后处置它时,可能会将异常重新抛出到另一个层,该层也会获得响应流,它将被处理掉并且不可读并因此而抛出更多异常。

2 个答案:

答案 0 :(得分:7)

简短的回答是,您不必处置它,尽管处置您拥有的任何IDisposable个对象是一个很好的练习。

实际上,尝试处理WebException.Response或从其返回的流会导致您提到的问题,因为您可能会遇到试图在上层调用链的异常处理程序中读取其属性的代码。

为什么不安置它是安全的原因是因为HttpWebRequest在它抛出WebException之前在内部从网络流产生内存流,并且底层网络流已经被关闭/处置。因此,它并没有真正关联任何非托管资源。我假设这是一个让处理异常更容易的决定。

不幸的是,MSDN文档对此行为没有任何解释。从技术上讲,实现可能在将来发生变化,从而导致代码无法处理HttpWebResponse和/或从WebException获得的关联流的问题,但鉴于许多应用程序依赖,此行为极不可能改变实现当前的行为。

我必须补充说,你应该处置你拥有的IDisposable个对象是一个好习惯。如果可能,请使用HttpClient课程,以便您根本不必处理这种情况。如果您不能,请考虑自己处理WebException并抛出新类型的异常但不会将WebException公开给您的代码的来电者,这样您就不会遇到这种情况处理后,调用者试图访问WebException.Response

免责声明:我为Microsoft工作,但这并不代表我的雇主或.NET Framework团队的观点。不保证暗示。

答案 1 :(得分:2)

您应该丢弃该流,因为它可能拥有资源。但只有当你完成它时才处理掉它。在您不再需要流之前,只需停止处理它。让流的最后一个用户处理它。

或许,您应该只调用GetResponseStream()一次并明确传递流,以便明确它是相同的流。