如何修复代码分析警告[重复]

Posted

技术标签:

【中文标题】如何修复代码分析警告[重复]【英文标题】:how to fix Code Analysis warnings [duplicate] 【发布时间】:2016-08-23 07:26:25 【问题描述】:

我有代码

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 行,这里是 return response;

之前的右括号

我该如何解决这个警告。

【问题讨论】:

【参考方案1】:

这两行引用了相同的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();

【讨论】:

【参考方案2】:

来自MSDN

StreamReader 对象在提供的 Stream 对象上调用 Dispose() 当 StreamReader.Dispose 被调用时。

这意味着 StreamReader 将在 Stream 对象上调用 Dispose 并且您的 using 语句也会这样做。替代方案可能是:

using (HttpWebResponse response = (HttpWebResponse)request.GetResponse())
    using (StreamReader reader = new StreamReader(response.GetResponseStream()))
    
       responce = reader.ReadToEnd();
    
return responce;

【讨论】:

【参考方案3】:

这里更深层次的问题是StreamReader的设计不正确;它不应该释放底层流,因为它不拥有它。

以下模式很常见:

public class Foo: IDisposable

    public Foo(Bar bar) ...


public class Bar: IDisposable  ... 

在处理foo时,它不应该自动为你处理bar,因为它不拥有barbarfoo 的用户提供的对象;因此,用户有责任照顾bar

这基本上就是您的代码中发生的事情;您正确地处理了stream,但StreamReader 也在处理与其业务无关的事情,也为您处理stream

所以,总结一下:您的代码是正确的。由于StreamReader 中的设计缺陷,您的正确代码正在产生需要注意的问题;重复调用Dispose()

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

【讨论】:

以上是关于如何修复代码分析警告[重复]的主要内容,如果未能解决你的问题,请参考以下文章

警告:不要多次处理对象[重复]

Roslyn:如何修复 RS2008 警告?

建立标准编码规则-CodeFixProvider 给代码分析器增加修复建议

代码生成器生成文件的代码分析 - 如何抑制警告?

如何从 Visual Studio 项目中获取抑制的代码分析警告列表?

Eclipse 快速修复