警告:不要多次处理对象[重复]

Posted

技术标签:

【中文标题】警告:不要多次处理对象[重复]【英文标题】:Warning: Do not dispose objects multiple times [duplicate] 【发布时间】:2014-08-15 17:06:31 【问题描述】:

编辑:

这个问题不是重复的!,也许是一个常见的问题“这个警告是什么意思?”但是当我问如何在特定代码中修复警告,我自己甚至不知道警告的含义。 -


VS 中的代码分析显示了这个警告:

CA2202 不要多次处理对象 Object 'OutputStream' 可以 在方法 'FileSplitter.Split(String, Long, 字符串,字符串,布尔值,布尔值)'。为了避免产生 System.ObjectDisposedException 你不应该调用 Dispose 超过 一次在一个对象上。:行: 490 WindowsApplication1 FileSplitter.vb 490

490 行是这样的:

End Using ' OutputStream

对于498 行中的另一个对象,它给了我同样的警告,这个:

End Using ' InputStream

但我认为我正确使用了 Using 关键字,并且我不会多次处理对象,如果我做错了什么,那么我该如何修复我的代码?

这是完整的块:

    ' 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

更新

添加 try/catch 块后,它仍然显示相同的警告。 如果我删除最后一次尝试/捕获,它只会显示 1 个警告。

    ' 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

【问题讨论】:

msdn.microsoft.com/en-us/library/ms182334.aspx 该示例几乎完全模仿了您的代码 所以,如果我理解得很好,问题是嵌套的内部using 它使用了另一个using 的资源,这意味着这条线?:Using BinaryWriter As New BinaryWriter(OutputStream)('因为我'我将 outputstream 资源传递给它,不是吗?),然后我只添加了一个 try/catch 块,如 msdn doc 中所述,谢谢您的帮助 At the end of the outer using statement, the stream object is released a second time 这个问题不是重复的!也许是一个常见的问题“这个警告是什么意思”?但当我询问如何修复特定代码中的警告时,它不是重复的,而且我自己不能。 忽略 CA2202 的唯一危险是 "Even if Dispose for the object is known to be safely callable multiple times [it is], the implementation might change in the future." 只需在该过程中添加 &lt;SuppressMessage("Microsoft.Usage", "CA2202")&gt; 即可在此处忽略它。另外:不要在你的捕获中执行Throw New...,因为这会弄乱原始异常的调用堆栈。而不是只做Throw 【参考方案1】:

这个问题的原因在您的代码中并不明显,而只是代码分析对所涉及对象的了解。

具体来说,当您构造BinaryReaderBinaryWriter 的实例时,您将底层流的所有权授予这些对象。因此,当您处置读取器/写入器对象时,流也会被处置。

因此,当您在处理完读取器/写入器对象后继续处理底层流时,代码分析会对此发出警告。

现在,这会是个问题吗?没有。

你应该修复它吗?一般来说,如果您启用代码分析,您应该修复所有错误或警告,除非您有充分的理由不这样做。

为了“正确”解决这个问题,习惯上将外部流包装在一个 try/finally 块中,并且只有在没有构造读取器/写入器的情况下,您的代码才能以某种方式到达 finally 块。

换句话说,如果您实际上并未将对象的所有权授予读取器/写入器对象,则您只想处置底层流。

我认为特定规则还提供了如何执行此操作的示例。

【讨论】:

就个人而言,在这种情况下我可能会要求代码分析停止。 我尝试通过添加两个 try/catch 块来修复警告,就像 MSDN 示例那样,但是警告仍然出现在两个“Stream.Dispose”指令中,我是什么做错了吗?请问你能修复我的代码吗?谢谢你的帮助

以上是关于警告:不要多次处理对象[重复]的主要内容,如果未能解决你的问题,请参考以下文章

在php中停止不推荐使用的警告[重复]

PEP 8警告“不要使用lambda表达式使用def”用于defaultdict lambda表达式[重复]

在 PHP 中处理警告 [重复]

后端处理高并发状态的多次重复请求

如何多次调用动画的函数[重复]

PHP session_destroy()警告会话对象销毁失败[重复]