D
David Browne
UConnection and UDataReader are "universal" objects able to connect to anySC said:Hi!
Here's my code:
.. . .
Alright, to me it doesn't seem like there's a whole lot in there.
data source by just specifying it using the enum. Anyways, when the program
exits, I get the following error (using a SQL server in this case):
Though, in debug, I cannot see anything wrong with my cn object. The statusHandle is not initialized.
mscorlib
at System.WeakReference.get_Target()
at System.Data.SqlClient.SqlConnection.CloseReader()
at System.Data.SqlClient.SqlConnection.Close()
at UniversalData.UConnection.Close()
at UniversalData.UData.Disconnect()
System.Object get_Target()
This all happens at the cn.Close() command of the Disconnect method.
says that it's an open connection and every property is set correctly.
the datareader when we forget to do so and the system disposes of theWhat can I do to avoid this error (and actually close the connection and
object)?
Your problem is here:
~UData()
{
//We do this just in case... It's safer!
Disconnect();
}
It is an error to access a SqlConnection in your finalizer in any way.
Period. There's some funky connection pooling stuff in SqlClient which is
incompatable with accessing the connection in a finalizer. By the time your
finalizer runs, your SqlConnection could be in use by another thread!
The problem you are actually seeing is because the finalization order is
indeterminate, so especially when the final GC is running at CLR shutdown
your finalizer can try to access previously finalized objects. You can work
around this particular issue by checking if the GC is at shutdown, and just
skipping your finalization code, but your real problem is that you shouldn't
be disconnecting in your finalizer at all.
Moreover UData should implement IDisposable, and IDisposable.Dispose should
close (or Dispose) the connection and then run GC.SupressFinalize(me), to
remove the instance from the Finalization Queue.
David