如何修复代码分析警告
本文关键字:警告 代码 何修复 | 更新日期: 2023-09-27 18:03:37
我有代码
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不要多次处置对象对象'stream'可以在方法' information . makehttpgetrequest (string)'中处置多次。以避免生成系统。你不应该在一个对象上多次调用Dispose。: Lines: 244 information .cs 244
第224行指的是第13行返回响应前的右括号;
如何修复此警告
这两行引用相同的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();
}
From MSDN
StreamReader对象在提供的Stream对象上调用Dispose()当StreamReader。
这意味着StreamReader会在Stream对象上调用Dispose,你的using语句也会这样做。其他选项可以是:
using (HttpWebResponse response = (HttpWebResponse)request.GetResponse())
using (StreamReader reader = new StreamReader(response.GetResponseStream()))
{
responce = reader.ReadToEnd();
}
return responce;
更深层次的问题是StreamReader
的设计是不正确的;它永远不应该释放底层流,因为它不拥有流。
下面的模式很常见:
public class Foo: IDisposable
{
public Foo(Bar bar) {...}
}
public class Bar: IDisposable { ... }
在释放foo
时,它不应该自动为你释放bar
,因为它不拥有bar
;bar
是foo
的用户提供的对象;因此,用户有责任照顾好bar
。
这就是代码中发生的事情;你正确地处理了stream
,但StreamReader
也在处理一些与它无关的事情,也为你处理了stream
。
StreamReader
中的设计缺陷,您的正确代码正在创建一个需要处理的问题;重复调用Dispose()
.
其他答案指出了解决这个问题的好方法,所以我不在这里重复代码。