1
votes

I have read the MSDN page on this: https://msdn.microsoft.com/en-us/library/ms182334.aspx

And also this SO answer: https://stackoverflow.com/a/32554589/2257227

But the following code still generates 2 CA2202 warnings for me:

FileStream fileStream = null;
BufferedStream bufferedStream = null;
try
{
    fileStream = File.Open(...);
    bufferedStream = new BufferedStream(fileStream);

    using (StreamReader streamReader = new StreamReader(bufferedStream))
    {
        ...
    }
}
finally
{
    if (bufferedStream != null)
    {
        bufferedStream.Dispose();
    }

    if (fileStream != null)
    {
        fileStream.Dispose();
    }
}

The "bufferedStream.Dispose()" line still gives the following two warnings:

Severity Code Description Project File Line Suppression State Warning CA2202 Object 'bufferedStream' can be disposed more than once in method 'Loader.UpdateIndex()'. To avoid generating a System.ObjectDisposedException you should not call Dispose more than one time on an object.: Lines: 930 Loader C:\Users\user\Loader\Loader.cs 930 Active

and

Severity Code Description Project File Line Suppression State Warning CA2202 Object 'fileStream' can be disposed more than once in method 'Loader.UpdateIndex()'. To avoid generating a System.ObjectDisposedException you should not call Dispose more than one time on an object.: Lines: 930, 935 Loader C:\Users\user\Loader\Loader.cs 930 Active

Presumably this is because fileStream could be disposed of more than once? But how can bufferedStream be disposed of more than once?

Edit: I've marked @Damien_The_Unbeliever's answer as correct. You can actually trim it down as well, because as was mentioned somewhere below, you don't need the bufferedReader variable. Here's what I ended up with. It's kinda ugly, but it works:

FileStream fileStream = null;
try
{
    fileStream = File.Open("iaushdiuh", FileMode.Open);

    fileStream = null;

    using (StreamReader streamReader = new StreamReader(fileStream))
    {
        streamReader.ReadLine();
    }
}
finally
{
    if (fileStream != null)
    {
        fileStream.Dispose();
    }
}
1
Do you use either fileStream or bufferedStream after you've passed them to other constructors? - Damien_The_Unbeliever
I find your edit disingenuous. The code I've placed in my answer compiles (with build analysis turned on) with zero warnings (provided the ... chunks are replaced with usable code), under VS 2017. If you have a reproducible code sample that can provoke warnings, please edit your question to include it. - Damien_The_Unbeliever
@Damien_The_Unbeliever Hey, sorry I didn't have time to look into this anymore at the time, but I've just come back to it and yes, your solution doesn't generate any warnings, thanks. I've marked the answer as correct and will edit my original post. - John Darvill

1 Answers

2
votes

If you don't use the underlying streams after you've "passed ownership" of these objects to other objects, you can silence the warning like this:

        FileStream fileStream = null;
        BufferedStream bufferedStream = null;
        try
        {
            fileStream = File.Open(...);
            bufferedStream = new BufferedStream(fileStream);

            fileStream = null;

            using (StreamReader streamReader = new StreamReader(bufferedStream))
            {

                bufferedStream = null;

                ...
            }
        }
        finally
        {
            if (bufferedStream != null)
            {
                bufferedStream.Dispose();
            }

            if (fileStream != null)
            {
                fileStream.Dispose();
            }
        }

You'll want the assignments to null to occur immediately following the constructor call that "takes ownership" of the disposable object. In this way, you ensure that if the constructor throws, you dispose the inner object and if the constructor succeeds then it is then going to arrange for disposal to occur.