【问题标题】:How can I prevent this code from disposing objects multiple times?如何防止此代码多次处理对象?
【发布时间】:2017-04-30 08:39:31
【问题描述】:

当我针对以下代码运行代码分析时:

Protected Function GetOrderEntry() As IList(Of OE)
    Dim results As IList(Of OE) = New List(Of OE)()
    Using connection As IDbConnection = DbProviderFactories.GetFactory("System.Data.SqlClient").CreateConnection()
        connection.ConnectionString = ConfigurationManager.AppSettings("OrderEnterConnection")
        Using command As IDbCommand = connection.CreateCommand()
            command.CommandTimeout = 120
            command.CommandText = "Exec up_ViewOrderDetail_2012_Order '" & MemberNo1.Value & "','" & CustNo.Value & "','DEFAULT','" & OrderNo.Value & "','" & DeliveryDate.SelectedDate & "','','','','1'"
            connection.Open()
            Try
                Dim reader As IDataReader = command.ExecuteReader()
                results = PopulateGrid(reader)
            Catch ex As SqlException
                results.Clear()
                connection.Close()
            End Try
        End Using
    End Using
    Return results
End Function

...我明白了,

"CA2202 不要多次释放对象 对象“连接”可以在方法“OrderConfirm.GetOrderEntry()”中多次释放。为避免生成 System.ObjectDisposedException,您不应多次调用 Dispose在一个物体上"

光标在最后的“结束使用”行;这如何被视为对象的双重处置?不是两个“Using”块都需要这样终止吗?

【问题讨论】:

  • stackoverflow.com/q/14706523/1070452 没有必要关闭连接,处理它就可以了。另一方面,该读者也应该被处置(好吧,无论如何,它们都是 IDisposable)

标签: sql-server vb.net using-statement idbcommand idbconnection


【解决方案1】:

我尝试删除 connection.createcommandconnection.Close()。 而且效果很好

Protected Function GetOrderEntry() As IList(Of OE)
    Dim results As IList(Of OE) = New List(Of OE)()
    Using connection As IDbConnection = DbProviderFactories.GetFactory("System.Data.SqlClient").CreateConnection()
        connection.ConnectionString = ConfigurationManager.AppSettings("OrderEnterConnection")
        Using command As New IDbCommand 
            Command.connection = connection
            command.CommandTimeout = 120
            command.CommandText = "Exec up_ViewOrderDetail_2012_Order '" & MemberNo1.Value & "','" & CustNo.Value & "','DEFAULT','" & OrderNo.Value & "','" & DeliveryDate.SelectedDate & "','','','','1'"
            connection.Open()
            Try
                Dim reader As IDataReader = command.ExecuteReader()
                results = PopulateGrid(reader)
               Reader.close()
            Catch ex As SqlException
                results.Clear()

            End Try
        End Using
    End Using
    Return results
End Function

【讨论】:

  • 我认为Using command As New IDbCommand 甚至不会编译,这让绿色的复选标记很好奇! ;-) 大概connection.CreateCommand() 被用来使代码提供者不可知,那么用什么来代替呢?它实际上是否删除了对 connection.Close() 的调用,从而消除了该消息,因为根据文档“关闭和处置在功能上是等效的”?
  • 让我更加困惑的是IDisposable 被纳入编译器,但我不相信编译器对IDbConnection.Close 方法给出了两个愚蠢的说法,所以应该删除它没有任何区别...usingIDisposable 上调用Dispose - 它不关心其他接口。
  • @Charleh CA* 消息来自代码分析,而不是编译器,所以我想他们可以更彻底地检查。我应该首先检查the docs,因为它们声明“方法实现包含可能导致多次调用 IDisposable.Dispose 或 Dispose 等效项的代码路径,例如某些类型上的 Close() 方法,在同一个对象上。” - 所以我认为除了 Using 之外,还有 connection.Close() 调用导致了警告。
  • 嗯,这就解释了,我猜 CA 是迂腐的!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2014-12-18
  • 2012-07-20
  • 1970-01-01
  • 1970-01-01
  • 2018-06-10
  • 1970-01-01
  • 2017-05-07
相关资源
最近更新 更多