我应该注意这个表面上荒谬的代码分析警告吗?

Should I heed this superficially nonsensical Code Analysis warning?

当我在 Visual Studio 2013 年对解决方案进行 select 分析 > 运行 代码分析时,我得到,“CA2202 不要多次处理对象对象 'fs' 可以在方法 'RoboReporterSQL.SaveReportDataToDB(string, string)' 中处理多次。为避免生成 System.ObjectDisposedException,您不应在一个对象上多次调用 Dispose。"

指示的代码行是:

fs.Close();

这里是上下文中的代码:

    internal static void SaveReportDataToDB(string filename, string 
RESTFilename)
    {
        if (RecordAlreadyExists(RESTFilename)) return;
        string EXCEL_FILE = "application/vnd.ms-excel";
        DateTime begDate = 
RoboReporterConstsAndUtils.GetBeginDate(RESTFilename);
        DateTime endDate = 
RoboReporterConstsAndUtils.GetEndDate(RESTFilename);

        var fs = new FileStream(filename, FileMode.Open, FileAccess.Read);
        BinaryReader br = new BinaryReader(fs);
        Byte[] bytes = br.ReadBytes((Int32)fs.Length);
        br.Close();
        fs.Close();

        using (var sqlConn = new SqlConnection(CPSConnStr))
        {
            var insertStr = "INSERT INTO ReportsGenerated (FileBaseName, 
ContentType, BinaryData, BeginDate, EndDate) " +
                             "VALUES (@FileBaseName, @ContentType, 
@BinaryData, @BeginDate, @EndDate)";

            using (var insertRptsGenerated = new SqlCommand(insertStr))
            {
                insertRptsGenerated.Connection = sqlConn;
                insertRptsGenerated.Parameters.Add("@FileBaseName", 
SqlDbType.VarChar, 100).Value = RESTFilename;
                insertRptsGenerated.Parameters.Add("@ContentType", 
SqlDbType.VarChar, 50).Value = EXCEL_FILE;
                insertRptsGenerated.Parameters.Add("@BinaryData", 
SqlDbType.Binary).Value = bytes;
                insertRptsGenerated.Parameters.Add("@BeginDate", 
SqlDbType.DateTime).Value = begDate;
                insertRptsGenerated.Parameters.Add("@EndDate", 
SqlDbType.DateTime).Value = endDate;
                sqlConn.Open();
                insertRptsGenerated.ExecuteNonQuery();
            }
        }
    }

因此警告声称如果我调用 "fs.Close();"

FileStream 将被关闭两次

尽管我不能肯定地反驳这一点,但我对此表示质疑,因为我没有看到它在其他地方被关闭。

毕竟它不在"using"块中,所以它是如何被关闭的?

问题是:我真的应该删除那行代码 ("fs.Close();") 吗?

注意:Resharper 对此丝毫没有抱怨[g] - "fs.Close();" 进入或退出,它都不会引发任何警告标志。

坦率地说,您不应该明确关闭这些流,您应该使用 using 块。

无论如何,它会向您发出警告,因为流已经关闭。当 readers/writers 包装一个流时,关闭它们也会关闭底层流。但是,readers/writers 中的某些选项让您可以选择让流保持打开状态。

在您的特定情况下,您可以使用 File class 中提供的一些其他方法,用一块石头杀死两只鸟。考虑使用 File.ReadAllBytes() 读取您的文件。

想补充一点,它仍然是一个毫无用处的警告。我从未见过 IDisposable 的任何实现,当您多次调用 Dispose 时会抛出 ObjectDisposedException。实际上在 IDisposable.Dispose 的文档中写了以下内容:

If an object's Dispose method is called more than once, the object must ignore all calls after the first one. The object must not throw an exception if its Dispose method is called multiple times

但是,您在流上调用了 Close,而不是 Dispose,虽然在这种情况下是相同的,但通常您确实不应该对已处置的对象调用任何非 Dispose 方法,因此至少将 Close 更改为 Dispose (或更好地全部包装在 using).