如何解决 CA2202:To 避免生成 System.ObjectDisposedException 警告

How To Solve CA2202:To avoid generating a System.ObjectDisposedException Warning

每次 visual studio 2015 年,当我 运行 Code Analysis 时,都会出现一些烦人的警告。所有这些都在这样的方法中:

这是我的方法:

public static JObject ReadJson(string file_path)
{
    try {
        JObject o1 = JObject.Parse(File.ReadAllText(file_path));
        using (StreamReader file = File.OpenText(file_path))
        {
            using (JsonTextReader reader = new JsonTextReader(file))
            {
                return (JObject)JToken.ReadFrom(reader);//the warning is here
            }
        }
    }
    catch
    {
        return default(JObject);
    }

}

那么为什么会出现这个警告?如何解决?而最重要的是什么 这个方法是我的错在我看来非常完美

警告说明

Severity Code Description Project File Line Warning CA2202 : Microsoft.Usage : Object 'file' can be disposed more than once in method 'JsonHelper.ReadJson(string)'. To avoid generating a System.ObjectDisposedException you should not call Dispose more than one time on an object.

MSDN:

Nested using statements (Using in Visual Basic) can cause violations of the CA2202 warning. If the IDisposable resource of the nested inner using statement contains the resource of the outer using statement, the Dispose method of the nested resource releases the contained resource. When this situation occurs, the Dispose method of the outer using statement attempts to dispose its resource for a second time.

问题:

using (StreamReader file = File.OpenText(file_path))
{
    using (JsonTextReader reader = new JsonTextReader(file))
    {
        return (JObject)JToken.ReadFrom(reader);//the warning is here
    }   //"file" will be disposed here for first time when "reader" releases it
}   //and here it will be disposed for the second time and will throw "ObjectDisposedException"

解法:

你需要这样做(当一切正常时将对象放置在finally块中,或者当发生错误时将对象放置在catch块中):

public static JObject ReadJson(string file_path)
{   
    StreamReader file = null;
    try {
        JObject o1 = JObject.Parse(File.ReadAllText(file_path));
        file = File.OpenText(file_path);
        using (JsonTextReader reader = new JsonTextReader(file))
        {
            return (JObject)JToken.ReadFrom(reader);
        }
    }
    catch
    {
        return default(JObject);
    }
    //dispose "file" when exiting the method
    finally
    {
        if(file != null)
            file.Dispose();
    }
}