我是否需要处理自定义 class 的实例以释放内存?那怎么办? VB.NET
Do I need to dispose an instance of my custom class to free up memory? Then how? VB.NET
我只是想在执行我的 SQL 查询时节省时间和代码来创建自定义 class,所以我这样创建:
Imports ADODB
Public Class MySQLConnection
Private SQLConnection As ADODB.Connection
Private SQLConnectionString As String = "Provider=SQLOLEDB;Data Source=111.111.10.201;Initial Catalog=dbSample;User ID=User;password=123456;"
Private SQLRecordSet As ADODB.Recordset
Public Recordset As ADODB.Recordset
Public Message As String
Public Function ExecuteSQLQuery(vQuery As String) As Boolean
Try
SQLConnection.Open(SQLConnectionString)
SQLRecordSet.CursorLocation = ADODB.CursorLocationEnum.adUseClient
SQLRecordSet.CursorType = ADODB.CursorTypeEnum.adOpenStatic
SQLRecordSet.LockType = ADODB.LockTypeEnum.adLockBatchOptimistic
SQLRecordSet.Open(vQuery, SQLConnection)
Recordset = SQLRecordSet 'passing the content of recordset to a public recordset for later use in my main program.
SQLRecordSet.Close()
SQLConnection.Close()
Message = "Query executed successfully."
Return True
Catch ex As Exception
Message = ex.Message
Return False
End Try
End Function
End Class
问题#1
但是由于我将在整个程序中创建此 class 的多个实例,我是否需要以某种方式处理实例以在使用后立即释放内存?
每当我需要执行查询时,我都会在我的主程序中使用下面的代码:
Private Sub COnnectToolStripMenuItem_Click(sender As Object, e As EventArgs) Handles COnnectToolStripMenuItem.Click
Dim DB_CONN As New MySQLConnection
If DB_CONN.ExecuteSQLQuery("SELECT * FROM tbl_Stores") Then
If DB_CONN.Recordset.RecordCount <> 0 Then
DB_CONN.Recordset.MoveFirst()
Do While Not DB_CONN.Recordset.EOF
'Read each record here
DB_CONN.Recordset.MoveNext()
Loop
End If
DB_CONN.Recordset.Close()
'==============================
'This is where I think I should dispose my class instance [DB_CON].
MsgBox("MESSAGE: " & DB_CONN.Message)
Else
MsgBox("ERROR: " & DB_CONN.Message)
End If
End Sub
问题 #2:
我如何在使用后处理 class 的实例?
我只想知道这个,这样我就可以清理我以前的程序了。
我在 Google 中找到的所有内容都是针对 C++ 的,所以我不确定它是否适用于 VB.Net
请帮忙! :(
如果我是你,我会考虑让 ExecuteSQLQuery
完全独立,这样它就需要一个 Action(Of ADODB.Recordset)
。然后它可以在执行后立即自行清理。
我最初会这样写:
Public Module MySQLConnection
Private SQLConnectionString As String = "Provider=SQLOLEDB;Data Source=111.111.10.201;Initial Catalog=dbSample;User ID=User;password=123456;"
Public Function ExecuteSQLQuery(vQuery As String, process As Action(Of ADODB.Recordset), message As Action(Of String)) As Boolean
Try
Dim conn As ADODB.Connection = New ADODB.Connection()
conn.Open(SQLConnectionString)
Dim rs As ADODB.Recordset = New ADODB.Recordset()
rs.CursorLocation = ADODB.CursorLocationEnum.adUseClient
rs.CursorType = ADODB.CursorTypeEnum.adOpenStatic
rs.LockType = ADODB.LockTypeEnum.adLockBatchOptimistic
rs.Open(vQuery, conn)
process?(rs)
rs.Close()
conn.Close()
message?("Query executed successfully.")
Return True
Catch ex As Exception
message?(ex.Message)
Return False
End Try
End Function
End Module
现在你可以这样使用它:
Private Sub COnnectToolStripMenuItem_Click2(sender As Object, e As EventArgs) Handles COnnectToolStripMenuItem.Click
Dim success As Boolean = MySQLConnection.ExecuteSQLQuery("SELECT * FROM tbl_Stores",
Sub(recordset)
If recordset.RecordCount <> 0 Then
recordset.MoveFirst()
Do While recordset.EOF
'Read each record here
recordset.MoveNext()
Loop
End If
End Sub, AddressOf MsgBox)
End Sub
甚至更好——使方法 return 成为某个值的可枚举对象:
Public Module MySQLConnection
Private SQLConnectionString As String = "Provider=SQLOLEDB;Data Source=111.111.10.201;Initial Catalog=dbSample;User ID=User;password=123456;"
Public Iterator Function ExecuteSQLQuery2(Of T)(vQuery As String, process As Func(Of ADODB.Recordset, T)) As IEnumerable(Of T)
Dim conn As ADODB.Connection = New ADODB.Connection()
conn.Open(SQLConnectionString)
Dim rs As ADODB.Recordset = New ADODB.Recordset()
rs.CursorLocation = ADODB.CursorLocationEnum.adUseClient
rs.CursorType = ADODB.CursorTypeEnum.adOpenStatic
rs.LockType = ADODB.LockTypeEnum.adLockBatchOptimistic
rs.Open(vQuery, conn)
If rs.RecordCount <> 0 Then
rs.MoveFirst()
Do While rs.EOF
Yield process(rs)
rs.MoveNext()
Loop
End If
rs.Close()
conn.Close()
End Function
End Module
那么你可以这样做:
Private Sub COnnectToolStripMenuItem_Click2(sender As Object, e As EventArgs) Handles COnnectToolStripMenuItem.Click
Dim values As IEnumerable(Of Integer) = MySQLConnection.ExecuteSQLQuery2(Of Integer)("SELECT * FROM tbl_Stores", Function(recordset) CType(recordset.Fields("Value").Value, Integer))
End Sub
我只是想在执行我的 SQL 查询时节省时间和代码来创建自定义 class,所以我这样创建:
Imports ADODB
Public Class MySQLConnection
Private SQLConnection As ADODB.Connection
Private SQLConnectionString As String = "Provider=SQLOLEDB;Data Source=111.111.10.201;Initial Catalog=dbSample;User ID=User;password=123456;"
Private SQLRecordSet As ADODB.Recordset
Public Recordset As ADODB.Recordset
Public Message As String
Public Function ExecuteSQLQuery(vQuery As String) As Boolean
Try
SQLConnection.Open(SQLConnectionString)
SQLRecordSet.CursorLocation = ADODB.CursorLocationEnum.adUseClient
SQLRecordSet.CursorType = ADODB.CursorTypeEnum.adOpenStatic
SQLRecordSet.LockType = ADODB.LockTypeEnum.adLockBatchOptimistic
SQLRecordSet.Open(vQuery, SQLConnection)
Recordset = SQLRecordSet 'passing the content of recordset to a public recordset for later use in my main program.
SQLRecordSet.Close()
SQLConnection.Close()
Message = "Query executed successfully."
Return True
Catch ex As Exception
Message = ex.Message
Return False
End Try
End Function
End Class
问题#1 但是由于我将在整个程序中创建此 class 的多个实例,我是否需要以某种方式处理实例以在使用后立即释放内存?
每当我需要执行查询时,我都会在我的主程序中使用下面的代码:
Private Sub COnnectToolStripMenuItem_Click(sender As Object, e As EventArgs) Handles COnnectToolStripMenuItem.Click
Dim DB_CONN As New MySQLConnection
If DB_CONN.ExecuteSQLQuery("SELECT * FROM tbl_Stores") Then
If DB_CONN.Recordset.RecordCount <> 0 Then
DB_CONN.Recordset.MoveFirst()
Do While Not DB_CONN.Recordset.EOF
'Read each record here
DB_CONN.Recordset.MoveNext()
Loop
End If
DB_CONN.Recordset.Close()
'==============================
'This is where I think I should dispose my class instance [DB_CON].
MsgBox("MESSAGE: " & DB_CONN.Message)
Else
MsgBox("ERROR: " & DB_CONN.Message)
End If
End Sub
问题 #2: 我如何在使用后处理 class 的实例?
我只想知道这个,这样我就可以清理我以前的程序了。
我在 Google 中找到的所有内容都是针对 C++ 的,所以我不确定它是否适用于 VB.Net
请帮忙! :(
如果我是你,我会考虑让 ExecuteSQLQuery
完全独立,这样它就需要一个 Action(Of ADODB.Recordset)
。然后它可以在执行后立即自行清理。
我最初会这样写:
Public Module MySQLConnection
Private SQLConnectionString As String = "Provider=SQLOLEDB;Data Source=111.111.10.201;Initial Catalog=dbSample;User ID=User;password=123456;"
Public Function ExecuteSQLQuery(vQuery As String, process As Action(Of ADODB.Recordset), message As Action(Of String)) As Boolean
Try
Dim conn As ADODB.Connection = New ADODB.Connection()
conn.Open(SQLConnectionString)
Dim rs As ADODB.Recordset = New ADODB.Recordset()
rs.CursorLocation = ADODB.CursorLocationEnum.adUseClient
rs.CursorType = ADODB.CursorTypeEnum.adOpenStatic
rs.LockType = ADODB.LockTypeEnum.adLockBatchOptimistic
rs.Open(vQuery, conn)
process?(rs)
rs.Close()
conn.Close()
message?("Query executed successfully.")
Return True
Catch ex As Exception
message?(ex.Message)
Return False
End Try
End Function
End Module
现在你可以这样使用它:
Private Sub COnnectToolStripMenuItem_Click2(sender As Object, e As EventArgs) Handles COnnectToolStripMenuItem.Click
Dim success As Boolean = MySQLConnection.ExecuteSQLQuery("SELECT * FROM tbl_Stores",
Sub(recordset)
If recordset.RecordCount <> 0 Then
recordset.MoveFirst()
Do While recordset.EOF
'Read each record here
recordset.MoveNext()
Loop
End If
End Sub, AddressOf MsgBox)
End Sub
甚至更好——使方法 return 成为某个值的可枚举对象:
Public Module MySQLConnection
Private SQLConnectionString As String = "Provider=SQLOLEDB;Data Source=111.111.10.201;Initial Catalog=dbSample;User ID=User;password=123456;"
Public Iterator Function ExecuteSQLQuery2(Of T)(vQuery As String, process As Func(Of ADODB.Recordset, T)) As IEnumerable(Of T)
Dim conn As ADODB.Connection = New ADODB.Connection()
conn.Open(SQLConnectionString)
Dim rs As ADODB.Recordset = New ADODB.Recordset()
rs.CursorLocation = ADODB.CursorLocationEnum.adUseClient
rs.CursorType = ADODB.CursorTypeEnum.adOpenStatic
rs.LockType = ADODB.LockTypeEnum.adLockBatchOptimistic
rs.Open(vQuery, conn)
If rs.RecordCount <> 0 Then
rs.MoveFirst()
Do While rs.EOF
Yield process(rs)
rs.MoveNext()
Loop
End If
rs.Close()
conn.Close()
End Function
End Module
那么你可以这样做:
Private Sub COnnectToolStripMenuItem_Click2(sender As Object, e As EventArgs) Handles COnnectToolStripMenuItem.Click
Dim values As IEnumerable(Of Integer) = MySQLConnection.ExecuteSQLQuery2(Of Integer)("SELECT * FROM tbl_Stores", Function(recordset) CType(recordset.Fields("Value").Value, Integer))
End Sub