Cannot get rid of CA2202 warning

604 Views Asked by At

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

There are 1 best solutions below

4
On BEST ANSWER

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.