Search code examples
.netvb.netdisposeusingobjectdisposedexception

Warning: Do not dispose objects multiple times


EDIT:

This question is not a duplicate!, maybe is a frequent question the "what means this warning?" but is not a duplicate when I'm asking how to fix the warning in a specific code, and I can't by myself even knowing the significate of the warning. –


A code analysis in VS shows me this warning:

CA2202 Do not dispose objects multiple times Object 'OutputStream' can be disposed more than once in method 'FileSplitter.Split(String, Long, String, String, Boolean, Boolean)'. To avoid generating a System.ObjectDisposedException you should not call Dispose more than one time on an object.: Lines: 490 WindowsApplication1 FileSplitter.vb 490

The line 490 is this:

End Using ' OutputStream

And it gives me the same warning for the other object in the line 498, this:

End Using ' InputStream

But I think that I'm using properly the Using keywords and I'm not disposing the objects more than once, If I'm doing something wrong then how I can fix my code?

This is the full block:

    ' Open the file to start reading bytes.
    Using InputStream As New FileStream(fInfo.FullName, FileMode.Open)

        Using BinaryReader As New BinaryReader(InputStream)

            While (InputStream.Position < InputStream.Length)

                ' Create the chunk file to Write the bytes.
                Using OutputStream As New FileStream(ChunkFile, FileMode.Create)

                    Using BinaryWriter As New BinaryWriter(OutputStream)

                        ' Read until reached the end-bytes of the input file.
                        While (SizeWritten < ChunkSize) AndAlso (InputStream.Position < InputStream.Length)
                            ' Some irrelevant code here...

                        End While ' (SizeWritten < ChunkSize) AndAlso (InputStream.Position < InputStream.Length)

                        OutputStream.Flush()

                    End Using ' BinaryWriter

                End Using ' OutputStream

            End While ' InputStream.Position < InputStream.Length

        End Using ' BinaryReader

    End Using ' InputStream

UPDATE

After adding the try/catch blocks it still showing the same warnings. If I delete the last try/catch it only shows 1 warning.

    ' Open the file to start reading bytes.
    Dim InputStream As Stream = Nothing

    Try

        InputStream = New FileStream(fInfo.FullName, FileMode.Open)
        Using BinaryReader As New BinaryReader(InputStream)

            While (InputStream.Position < InputStream.Length)

                ' Create the chunk file to Write the bytes.
                Dim OutputStream As Stream = Nothing

                Try
                    OutputStream = New FileStream(ChunkFile, FileMode.Create)
                    Using BinaryWriter As New BinaryWriter(OutputStream)

                        ' Read until reached the end-bytes of the input file.
                        While (SizeWritten < ChunkSize) AndAlso (InputStream.Position < InputStream.Length)

                    End Using ' BinaryWriter

                Catch ex As Exception
                    Throw New Exception(ex.Message)

                Finally
                    If OutputStream IsNot Nothing Then
                        OutputStream.Dispose()
                    End If

                End Try

            End While ' InputStream.Position < InputStream.Length

        End Using ' BinaryReader

    Catch ex As Exception
        Throw New Exception(ex.Message)

    Finally
        If InputStream IsNot Nothing Then
            InputStream.Dispose()
        End If

    End Try

Solution

  • The reason for this problem is not apparent from your code, but is just knowledge that code analysis has about the objects involved.

    Specifically, when you construct an instance of either BinaryReader or BinaryWriter, you give ownership of the underlying stream over to those objects. Thus, when you dispose of the reader/writer objects, the streams are disposed as well.

    As such, when you then go on to dispose of the underlying streams after having disposed of the reader/writer objects, code analysis warns about this.

    Now, will this be a problem? No.

    Should you fix it? In general, if you enable code analysis, you should fix all errors or warnings unless you have a really good reason not to.

    To "correctly" get rid of the issue, it is customary to wrap the outer stream in a try/finally block and only dispose of this is somehow your code reaches the finally block without the reader/writer having been constructed.

    In other words, you would only want to dispose of the underlying stream if you didn't actually give ownership of the object to the reader/writer objects.

    I think the particular rule also gives an example of how to do this.