如何修复代码分析警告

时间:2016-08-23 07:26:26

标签: c# code-analysis

我有一个代码

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行是返回响应之前的结束括号;

如何修复此警告。

3 个答案:

答案 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; barfoo的用户提供的对象;因此,用户有责任照顾bar

这基本上是代码中发生的事情;你正确地照顾stream,但StreamReader也正在处理一些与其无关的事情,也为你处理stream

所以,结束:你的代码是正确的。由于StreamReader中的设计缺陷,您的正确代码会产生一个需要注意的问题;重复拨打Dispose()

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