我是否应该注意这种表面上荒谬的代码分析警告?

时间:2016-05-26 17:53:43

标签: c# filestream dispose objectdisposedexception

当我选择Analyze>关于Visual Studio 2013中的解决方案的RUn代码分析,我得到,“ 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正在关闭两次

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

毕竟,它不在“使用”块中,所以它是如何被关闭的?

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

注意:Resharper并没有对此表示怀疑 - 用“fs.Close();”无论是进出,它都不会引起任何警告标志。

2 个答案:

答案 0 :(得分:4)

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

无论如何,它会向您发出警告,因为该流已经关闭。当读者/编写者包装流时,关闭它们也将关闭基础流。一些读者/作者可以选择让流保持打开状态。

在您的特定情况下,您可以使用File课程中提供的其他一些方法一举两得。请考虑使用File.ReadAllBytes()来读取您的文件。

答案 1 :(得分:3)

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

  

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

,则该对象不得抛出异常

但是,你在你的流上调用Close,而不是Dispose,虽然在这种情况下它是相同的,但一般来说你确实不应该在被处置对象上调用任何非Dispose方法,所以至少改变Close to处置(或更好地包装所有使用)。