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

Should WebException.Response.GetResponseStream() be close / disposed?

当我捕捉到 .NET WebException 时,我是否应该关闭/处置 Response.GetResponseStream()

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

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

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

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

或许,您应该只调用 GetResponseStream() 一次并显式地传递流,以便清楚它是同一个流。

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

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

之所以不去dispose是安全的,是因为HttpWebRequest在抛出之前,内部从网络流中做了一个内存流WebException,底层的网络流已经closed/disposed。因此,此时它实际上并没有关联任何非托管资源。我认为这是为了更容易处理异常而做出的决定。

遗憾的是,MSDN 文档对此行为没有任何解释。从技术上讲,实现可能会在未来发生变化,导致您的代码出现问题,无法处理您从 WebException 获得的 HttpWebResponse and/or 关联流,但这种行为极不可能改变实现,因为有很多应用程序取决于当前行为。

我必须补充一点,你应该处置你拥有的 IDisposable 个对象是一个好习惯。如果可能,请使用 HttpClient class 代替,这样您就完全不必处理这种情况。如果不能,请考虑自己处理 WebException 并抛出不会将 WebException 暴露给代码调用者的新型异常,这样您就不会 运行 陷入困境调用者在您处理后尝试访问 WebException.Response 的位置。

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