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



当我在Visual Studio 2013中选择"分析> RUn Code Analysis on Solution"时,我得到"CA2202 不要多次释放对象 Object '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",则文件流正在关闭两次。关闭();"

虽然我没有肯定地反驳这一点,但我质疑它,因为我不认为它在其他地方关闭。

毕竟,它

不在"使用"块中,那么它是如何关闭的呢?

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

注意:Resharper 对此没有抱怨 - 用"fs.关闭();" 输入或输出,无论哪种方式都不会引发警告标志。

坦率地说,你不应该显式关闭这些流,你应该使用using块。

无论如何,它会给您该警告,因为流已经关闭。 当读取器/写入器包装流时,关闭它们也会关闭基础流。 但是,某些阅读器/编写器为您提供了使流保持打开状态的选项。

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

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

如果多次调用对象的 Dispose 方法,则该对象必须忽略第一个调用之后的所有调用。如果多次调用对象的 Dispose 方法,则不得引发异常

但是,您在流上调用 Close,而不是 Dispose,虽然在这种情况下它是相同的,但一般来说,您确实不应该在已释放的对象上调用任何非 Dispose 方法,因此至少将 Close 更改为 Dispose(或更好地包装所有使用)。

相关内容

  • 没有找到相关文章

最新更新