请查看以下代码:
Public Class Form1
Private _ConString As String
Private Sub Form1_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
Dim objDR As SqlDataReader
Dim objCommand As SqlCommand
Dim objCon As SqlConnection
Dim id As Integer
Try
_ConString = ConfigurationManager.ConnectionStrings("TestConnection").ToString
objCon = New SqlConnection(_ConString)
objCommand = New SqlCommand("SELECT * FROM Person")
objCommand.Connection = objCon
objCon.Open()
objDR = objCommand.ExecuteReader(ConnectionState.Closed)
Do While objDR.Read
id = objDR("URN")
Loop
objDR.Close() 'line 16
Catch ex As Exception
throw
Finally
End Try
End Sub
End Class
连接对象在第16行关闭。请查看下面的代码:
Private Sub Form1_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
Dim objDR As SqlDataReader
Dim objCommand As SqlCommand
Dim objCon As SqlConnection
Dim id As Integer
Try
_ConString = ConfigurationManager.ConnectionStrings("TestConnection").ToString
objCon = New SqlConnection(_ConString)
objCommand = New SqlCommand("SELECT * FROM Person")
objCommand.Connection = objCon
objCon.Open()
Using objCon
Using objCommand
objDR = objCommand.ExecuteReader()
Do While objDR.Read
id = objDR("URN")
Loop
End Using
End Using
objDR.Close() 'line 16
Catch ex As Exception
throw
Finally
End Try
End Sub
在这两种情况下,我都注意到连接对象和命令对象在关闭后仍然具有状态(通过按照代码示例1关闭数据读取器或按照代码示例2移动到Using语句之外)。这可能是内存泄漏的来源吗?
答案 0 :(得分:0)
你应该做这样的事情......
Using Conn as new SqlConnection(_ConString)
Dim cmd as New SqlCommand(Conn, "Select * FROM Person");
id = Convert.ToInt32(cmd.ExecuteScalar())
End Using
如果必须,请尝试将其包裹起来,但前提是您要以某种方式处理它。 (一个简单的“投掷”不处理任何事情。)
您还使用DataReader(仅迭代,仅转发)数据访问组件来获取单个值。您可能希望使用ExecuteScalar()来简化该代码。
除此之外,不要将“Disposed”混淆为与“Closed”相同。 .NET框架为您管理垃圾收集。如果你想处理连接和命令对象,请在它们上面调用.Dispose()(但是Using会为你处理这个!!!)
答案 1 :(得分:0)
re:这可能是内存泄漏的来源吗? 不,它不应该是。
另外,这个:
objDR = objCommand.ExecuteReader()
Do While objDR.Read
id = objDR("URN")
Loop
看起来很糟糕,因为它遍历所有行并覆盖id值。最后一行设置以ID中的值结束。您从一组多行中获取一个结果。如果您只想要来自max(URN)
的{{1}},您可以编写命令以返回该结果。