C#: 使用 "Using" 语句处理 HttpWebRequests/HttpWebResponses

22

Jon Skeet在我的SOApiDotNet代码(一个用于pre-alpha Stack Overflow API的.NET库)中通过Twitter发表评论

@maximz2005 我从快速浏览源代码中发现了一件事情:你没有处理WebResponses。使用"using"语句吧。

他指出我需要使用"using"语句来包装这些Web会话。然而,我有一个问题:我应该从HttpWebRequest开始全部包装,还是在"using"语句之外创建WebRequest,然后在其中包装Response?我有一种感觉,两者的区别在于前者会将两个对象都处理掉 - 这样正确吗?

提前感谢。

3个回答

50

HttpWebRequest本身不需要进行处理,不像HttpWebResponse。你应该将可处理的资源包装在使用using语句中以允许及早和决定性地清除。正确实现的IDisposable模式允许多次调用Dispose而没有任何问题,因此即使外部使用语句包装了资源,在其自己的处理期间,它会处理内部使用语句资源,这仍然是可以接受的。

代码示例

var request = (HttpWebRequest)WebRequest.Create("example.com"); 
using (var response = (HttpWebResponse)request.GetResponse()) 
{ 
    // Code here 
}

那我应该在外面声明..Request,还是怎么样? - Maxim Zaslavsky
2
是的,这意味着你需要执行 var request = (HttpWebRequest)WebRequest.Create("http://example.com"); 使用 (var response = (HttpWebResponse)request.GetResponse()) { // 这里放置代码 } - Benjamin Podszun
1
@Dzmitry,@Benjamin。我在你的答案中添加了Benjamin的代码示例。 - Jan Jongboom

6

使用 using() {} 块包装的所有内容(即第一个括号内的内容)在离开作用域时都被处理。

我到目前为止还没有使用过你的库(看起来很不错),但我认为你应该明确地处理每个 IDisposable 对象,也就是说你需要负责并且不返回给调用者。

顺便提一下,因为我看到很多人在处理多个对象时遇到了困难:可以使用 using 块嵌套来代替显式处理。

using (var foo = SomeIDisposable) {
  using (var bar = SomeOtherIDisposable) {
  }
}

如果需要很多垂直空间,您可以编写

using (var foo = SomeIDisposable)
using (var bar = SomeOtherIDisposable) {
}

你的第二段(我相信是正确的)与第一段相矛盾。如果 using 块内的所有内容都被处理,那么你就不需要内部的 using 语句了。 - Tomas
请查看我的更新帖子:当您离开以下代码块(即此部分:{...})时,使用(...)内的所有内容都将被处理。 - Benjamin Podszun

1
为了防止内存泄漏,您应该在每个实现IDisposable的对象上调用Dispose。您可以使用using关键字来确保调用Dispose方法(无意冒犯),因为它只是try-finally块的语法糖。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接