我有一个代码
public String makeHttpGetRequest(String url)
{
try
{
string responce = string.Empty;
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url);
request.AutomaticDecompression = DecompressionMethods.GZip;
using (HttpWebResponse response = (HttpWebResponse)request.GetResponse())
using (Stream stream = response.GetResponseStream())
using (StreamReader reader = new StreamReader(stream))
{
responce = reader.ReadToEnd();
}
return responce;
}
catch (Exception e)
{
Console.WriteLine("Internet Connection error" + e.Message);
return null;
}
}
当我在Visual Studio中运行代码分析
时,我收到警告CA2202多次弃置物品对象'流'可以在方法' InformationIO.makeHttpGetRequest(string)'中多次处理。为避免生成System.ObjectDisposedException,您不应在对象上多次调用Dispose:Lines:244 InformationIO.cs 244
第224行在此处引用第13行是返回响应之前的结束括号;
如何修复此警告。
答案 0 :(得分:1)
这两行引用相同的using
,并尝试将其处理两次:
using (HttpWebResponse response = (HttpWebResponse)request.GetResponse())
{
Stream stream = response.GetResponseStream());
using (StreamReader reader = new StreamReader(stream))
{
responce = reader.ReadToEnd();
}
}
删除第二个finally
块(在您拥有的三个块中),因为在这种情况下它是不必要的。
Stream stream = null;
try
{
using (HttpWebResponse response = (HttpWebResponse)request.GetResponse())
{
stream = response.GetResponseStream());
using (StreamReader reader = new StreamReader(stream))
{
responce = reader.ReadToEnd();
}
}
}
finally
{
// check if stream is not null (although it should be), and dispose of it
if (stream != null)
stream.Dispose();
}
如果您希望确实确定要处理该流,请添加{{1}}块:
{{1}}
答案 1 :(得分:0)
来自MSDN
StreamReader对象在提供的Stream对象上调用Dispose() 当调用StreamReader.Dispose时。
这意味着StreamReader将调用Dispose on Stream对象,你的using语句也会这样做。替代方案可能是:
using (HttpWebResponse response = (HttpWebResponse)request.GetResponse())
using (StreamReader reader = new StreamReader(response.GetResponseStream()))
{
responce = reader.ReadToEnd();
}
return responce;
答案 2 :(得分:0)
这里更深层次的问题是StreamReader
的设计不正确;它永远不应该处理底层流,因为它不拥有它。
以下模式很常见:
public class Foo: IDisposable
{
public Foo(Bar bar) {...}
}
public class Bar: IDisposable { ... }
处置foo
时,不应自动为您处置bar
,因为它不属于bar
; bar
是foo
的用户提供的对象;因此,用户有责任照顾bar
。
这基本上是代码中发生的事情;你正确地照顾stream
,但StreamReader
也正在处理一些与其无关的事情,也为你处理stream
。
所以,结束:你的代码是正确的。由于StreamReader
中的设计缺陷,您的正确代码会产生一个需要注意的问题;重复拨打Dispose()
。
其他答案指出了解决问题的好方法,所以我不会在这里复制代码。