如何正确处理WebResponse实例?

Mar*_*cus 21 .net c# idisposable webresponse

通常,使用WebRequest编写类似这样的代码来下载一些数据.

using(WebResponse resp = request.GetResponse())  // WebRequest request...
   using(Stream str = resp.GetResponseStream())  
      ; // do something with the stream str
Run Code Online (Sandbox Code Playgroud)

现在,如果抛出WebException,WebException会引用WebResponse对象,该对象可能会或可能不会调用Dispose(取决于发生异常的位置,或者响应类的实现方式) - 我不知道.

我的问题是如何处理这个问题.是否应该编写一个非常防御性的编码,并在WebException对象中处理响应(这有点奇怪,因为WebException不是IDisposable).或者是否应该忽略这一点,可能访问已处置的对象或从不处置IDisposable对象?WebException.Response的MSDN文档中给出的示例完全不合适.

Chr*_*ter 16

我已经快速浏览了Reflector,现在可以说:

  • WebResponse作为一个抽象类,将其所有关闭/处置行为委托给其派生类.
  • HttpWebResponse作为派生类,你几乎肯定在这里使用它的close/dispose方法,只关心处理实际的响应流.其余的阶级国家可以留给GC的招标怜悯.

因此,只要符合以下条件,就异常处理做任何你喜欢的事情都可能是安全的:

  • 当您从读取响应流WebResponse中的try块,其封装在一个using模块.
  • 如果您读取响应流WebException中的catch块,其封装在一个using块为好.
  • 没有必要担心处置WebException自己.


fyj*_*ham 2

我非常确定,当您有一个 using 语句时,无论您如何退出 using 块(无论是通过异常、返回还是简单地执行函数),对象都会被释放。

我怀疑如果您让它离开 using 块,您会发现 WebException 内的对象已经被释放。

请记住,处置对象并不一定会阻止以后访问它。稍后尝试调用它的方法可能是不可预测的,导致它自己的异常或非常奇怪的行为(因此我不推荐它)。但即使如此,即使您将其丢弃,对象的很大一部分仍然会被垃圾收集器留下,因此仍然可以访问。处置的目的通常是清理资源句柄(如本例中的活动 TCP 连接),出于性能原因,在垃圾收集器找到它们之前,您实际上无法将其闲置。我提到这一点只是为了澄清它的处置和保存对它的引用的例外并不相互排斥。