Should I heed this superficially nonsensical Code Analysis warning? [duplicate]

假如想象 提交于 2019-12-12 03:16:53

问题


When I select Analyze > RUn Code Analysis on Solution in Visual Studio 2013, I get, "CA2202 Do not dispose objects multiple times Object 'fs' can be disposed more than once in method 'RoboReporterSQL.SaveReportDataToDB(string, string)'. To avoid generating a System.ObjectDisposedException you should not call Dispose more than one time on an object."

The indicated line of code is:

fs.Close();

And here is the code in context:

    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();
            }
        }
    }

So the warning is claiming that the FileStream is being closed twice if I call "fs.Close();"

Although I don't refute that with certainty, I question it because I don't see it being elsewhere closed.

After all, it is not in a "using" block, so how is it being closed?

The question is: should I really remove that line of code ("fs.Close();")?

Note: Resharper did not whin[g]e a whit about this - with "fs.Close();" in or out, it raises no warning flags either way.


回答1:


Frankly you shouldn't be closing those streams explicitly, you should be using using blocks.

Anyway, it gives you that warning because the stream is already closed. When readers/writers wrap a stream, closing them will close the underlying stream as well. Some of readers/writers give you the option to leave the stream open however.

In your particular case, you can kill two birds with one stone by using some of the other methods available in the File class. Consider using File.ReadAllBytes() to read in your file.




回答2:


Want to add that it's still quite useless warning. I never saw any implementation of IDisposable which would throw ObjectDisposedException when you call Dispose multiple times. Actually in documentation of IDisposable.Dispose the following is written:

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

However, you call Close on your stream, not Dispose, and while in this case it's the same, in general you indeed should not call any non-Dispose methods on disposed objects, so at least change Close to Dispose (or better wrap all in using).



来源:https://stackoverflow.com/questions/37467900/should-i-heed-this-superficially-nonsensical-code-analysis-warning

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!