如何修复代码分析警告

本文关键字:警告 代码 何修复 | 更新日期: 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;barfoo的用户提供的对象;因此,用户有责任照顾好bar

这就是代码中发生的事情;你正确地处理了stream,但StreamReader也在处理一些与它无关的事情,也为你处理了stream

所以,总结一下:你的代码是正确的。由于StreamReader中的设计缺陷,您的正确代码正在创建一个需要处理的问题;重复调用Dispose() .

其他答案指出了解决这个问题的好方法,所以我不在这里重复代码。