【问题标题】:Should WebException.Response.GetResponseStream() be close / disposed?WebException.Response.GetResponseStream() 应该关闭/处置吗?
【发布时间】:2015-12-29 17:55:06
【问题描述】:

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

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

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

我处理了流,这引起了大问题。因为GetResponseStream()(总是?/有时?)返回相同的实例。因此,当我获取响应流然后将其释放时,可能会将异常重新抛出到也获取响应流的另一层,它将已被释放且不可读,并因此引发更多异常。

【问题讨论】:

标签: c# .net idisposable httpwebresponse webexception


【解决方案1】:

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

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

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

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

我必须补充一点,你应该处置你拥有的 IDisposable 对象是一个很好的做法。如果可能,请改用HttpClient 类,这样您就根本不必处理这种情况。如果不能,请考虑自己处理WebException 并抛出不会将WebException 暴露给代码调用者的新型异常,这样您就不会遇到调用者试图访问@ 的情况987654332@你处理后。

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

【讨论】:

    【解决方案2】:

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

    您可能应该只调用一次GetResponseStream() 并明确传递流,以便清楚地知道它是同一个流。

    【讨论】:

    • 您能否分享此信息的来源?您是否在 MSDN 中看到任何暗示这一点的内容?您对GetResponseStream 有丰富的经验吗?或者它只是对它可能如何工作的一般猜测?根据我的经验,这个 API 的结果并不好。
    • 如果您没有相反的信息,则必须处置所有一次性资源。即使他们当前的实现不需要它(我并不是说这里就是这种情况)它可能会在未来发生变化。因此,反编译代码并不是一个很靠谱的答案。 GetResponseStream 似乎很可能持有资源。如果你想跳过处置,你必须非常确定。
    • 按照惯例,双重处理在 .NET 中始终是安全的。处置一个对象并不会删除它。
    • 没错,但问题不在于双重处置。早弃了吧这是一个体系结构的想法:创建一个为 IDisposable 对象保留引用计数的类。这样,您可以以狂野的方式绕过流,一旦最后一个所有者完成,它就会被处理掉。到目前为止,我从来没有这种需要,但它可能对你的情况有所帮助。
    • 这实际上是一个好点。到目前为止,我一直设法构造代码,以便我只调用该函数一次。我认为无论如何这都是很好的风格。
    猜你喜欢
    • 2015-02-13
    • 2011-10-08
    • 2022-11-06
    • 2013-08-05
    • 2011-09-01
    • 2023-01-06
    • 2023-03-14
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多