L
lothar.behrens
Hi,
I have figured out that .NET CLR implements object destruction on the
knowledge of usage of
these objects. My DBHelper class closes the connection when refcount
goes to zero. That happens inside Finalize.
The sample code at the end crashes when I not do a call to getReader
with an empty string.
That is used as a Dummy for ' This object is used until here '
information.
If I use the last getReader line, All is fine.
I came from C++ and expected that GC doesn't touch objects in the same
scope (stack).
This makes me struggling on how to close connections automatically in
Finalize whithout
explicitly set the object to NULL. (In C++ I have smart pointers that
do this for me)
Any Ideas ?
Thanks, Lothar
Public Class DBHelper
Shared conn As SqlClient.SqlConnection
Shared refcount As Integer
Public Sub New(ByVal where As String)
refcount = refcount + 1
End Sub
Public Function getReader(ByVal SQL As String) As
SqlClient.SqlDataReader
Dim mycmd As SqlClient.SqlCommand
Dim reader As SqlClient.SqlDataReader = Nothing
' Return on empty query
If SQL = "" Then
Return Nothing
End If
Try
If conn Is Nothing Then
conn = New
SqlClient.SqlConnection("connectionstring")
End If
conn.Open()
Catch ex As Exception
' Log some information
conn = Nothing
Return Nothing
End Try
mycmd = conn.CreateCommand
mycmd.CommandText = SQL
Try
reader = mycmd.ExecuteReader()
'CommandBehavior.CloseConnection)
Catch ex As Exception
' Log some information
reader = Nothing
Return Nothing
End Try
Return reader
End Function
Protected Overrides Sub Finalize()
If refcount > 0 Then
refcount = refcount - 1
If refcount = 0 Then
Try
conn.Close()
conn = Nothing
Catch ex As Exception
End Try
End If
End If
MyBase.Finalize()
End Sub
Sample:
Public Sub SomeFunction()
Dim dbHelper As DBHelper = New DBHelper()
Dim reader As SqlClient.SqlDataReader
Dim SQL As String = "SELECT * from SomeTable"
reader = dbHelper.getReader(SQL)
GC.Collect() ' A
Collect to be appear explicitly or indirectly in
' my code
System.Threading.Thread.Sleep(10) ' Some time
consumption
If Not reader Is Nothing Then
While
reader.Read() ' Crash
Dim SomeField As String = reader.GetValue(0)
End While
End If
'dbHelper.ExecuteScalar("") ' Doesn't crash when
this line is uncommented.
End Sub
I have figured out that .NET CLR implements object destruction on the
knowledge of usage of
these objects. My DBHelper class closes the connection when refcount
goes to zero. That happens inside Finalize.
The sample code at the end crashes when I not do a call to getReader
with an empty string.
That is used as a Dummy for ' This object is used until here '
information.
If I use the last getReader line, All is fine.
I came from C++ and expected that GC doesn't touch objects in the same
scope (stack).
This makes me struggling on how to close connections automatically in
Finalize whithout
explicitly set the object to NULL. (In C++ I have smart pointers that
do this for me)
Any Ideas ?
Thanks, Lothar
Public Class DBHelper
Shared conn As SqlClient.SqlConnection
Shared refcount As Integer
Public Sub New(ByVal where As String)
refcount = refcount + 1
End Sub
Public Function getReader(ByVal SQL As String) As
SqlClient.SqlDataReader
Dim mycmd As SqlClient.SqlCommand
Dim reader As SqlClient.SqlDataReader = Nothing
' Return on empty query
If SQL = "" Then
Return Nothing
End If
Try
If conn Is Nothing Then
conn = New
SqlClient.SqlConnection("connectionstring")
End If
conn.Open()
Catch ex As Exception
' Log some information
conn = Nothing
Return Nothing
End Try
mycmd = conn.CreateCommand
mycmd.CommandText = SQL
Try
reader = mycmd.ExecuteReader()
'CommandBehavior.CloseConnection)
Catch ex As Exception
' Log some information
reader = Nothing
Return Nothing
End Try
Return reader
End Function
Protected Overrides Sub Finalize()
If refcount > 0 Then
refcount = refcount - 1
If refcount = 0 Then
Try
conn.Close()
conn = Nothing
Catch ex As Exception
End Try
End If
End If
MyBase.Finalize()
End Sub
Sample:
Public Sub SomeFunction()
Dim dbHelper As DBHelper = New DBHelper()
Dim reader As SqlClient.SqlDataReader
Dim SQL As String = "SELECT * from SomeTable"
reader = dbHelper.getReader(SQL)
GC.Collect() ' A
Collect to be appear explicitly or indirectly in
' my code
System.Threading.Thread.Sleep(10) ' Some time
consumption
If Not reader Is Nothing Then
While
reader.Read() ' Crash
Dim SomeField As String = reader.GetValue(0)
End While
End If
'dbHelper.ExecuteScalar("") ' Doesn't crash when
this line is uncommented.
End Sub