如何修复代码分析警告
我有一个代码如何修复代码分析警告
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
line 224指的是第13行在这之前的结尾括号return responce;
我该如何解决此警告。
从MSDN
StreamReader对象所提供的流对象时 StreamReader.Dispose上调用调用Dispose()。
这意味着StreamReader将调用Stream对象上的Dispose,并且您的using语句也会这样做。选择可以是:
using (HttpWebResponse response = (HttpWebResponse)request.GetResponse())
using (StreamReader reader = new StreamReader(response.GetResponseStream()))
{
responce = reader.ReadToEnd();
}
return responce;
这两行引用相同的stream
,并会尝试处理两次:
using (Stream stream = response.GetResponseStream())
using (StreamReader reader = new StreamReader(stream))
取下第二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();
}
这里的更深层次的问题是,StreamReader
设计是不正确;它不应该配置底层的流,因为它不会自己它。
下面的模式是很常见:
public class Foo: IDisposable
{
public Foo(Bar bar) {...}
}
public class Bar: IDisposable { ... }
处置时foo
,它不应该自动为您处理bar
,因为它并不拥有bar
; bar
是由foo
的用户提供的对象;因此其用户负责照顾bar
。
这实际上是在你的代码中发生的事情;你正在照顾stream
,但StreamReader
也照顾一些不是真正的业务,也为你处置stream
。
因此,总结:你的代码是正确的。由于StreamReader
中的设计缺陷,您的正确代码正在创建需要照顾的问题;重复拨打Dispose()
。
其他答案指出了很好的方法来解决这个问题,所以我不会在这里重复代码。