DbConnection

  • Thread starter Thread starter Guest
  • Start date Start date
G

Guest

Hello, Newsgroupians:

I am creating a wrapper for (I)DbConnection. I can connect to a database
and place queries; however, I'm having some problems with my wrapped class.

In short, I have the following...

public class CDB
{
protected System.Data.IDbConnection m_conn;

...

}

Now, I've read that I should ALWAYS close my connection when I'm finished.
So when my class that wraps the connection is ready for garbage collection, I
close the connection in the destructor. It is as follows...

~CDB()
{
if (this.m_conn.State == System.Data.ConnectionState.Open)
{
try
{
this.m_conn.Close();
}
catch(Exception e)
{
Console.WriteLine(e.Message);
Console.ReadLine(); // I add this just so I can see the message.
}
}
}

The problem is I always receive the exception -- which is an
InvalidOperationException -- "Handle is not initialized." Any ideas what I
am doing wrong, or how to rectify the situation? Thank you. Should you need
more of my code, please do not hesistate to ask. I just thought the other
code was irrelevant in this situation. Thank you again.


Trecius
 
Which part of the code throws the exception? When you check the connection
status or when you try to close the connection?

Adrian.
 
Trecius,

You shouldn't be cleaning up the database connection like this. Rather,
you should be implementing the IDisposable interface on your class, and then
calling the Dispose method on the database connection in your implementation
of IDisposable.

For more information on implementing the IDisposable interface, look at
the section of the MSDN documentation titled "Implementing a Dispose
Method", located at:

http://msdn2.microsoft.com/en-us/library/aa720161(VS.71).aspx
 
Don't use a finalizer. Make your class implement IDisposable and in
Dispose() call Close() on the connection. Any time your custom class
contains an instance variable which is IDisposable, your class also
needs to be IDisposable.

Since the connection is itself a managed object it's improper for you
to reference it at all in a finalzer (it may have been finalized
already).

HTH,

Sam
 
The method that is creating the exception is this.m_conn.Close().


Trecius

Adrian Voicu said:
Which part of the code throws the exception? When you check the connection
status or when you try to close the connection?

Adrian.
--
[Please mark my answer if it was helpful to you]




Trecius said:
Hello, Newsgroupians:

I am creating a wrapper for (I)DbConnection. I can connect to a database
and place queries; however, I'm having some problems with my wrapped class.

In short, I have the following...

public class CDB
{
protected System.Data.IDbConnection m_conn;

...

}

Now, I've read that I should ALWAYS close my connection when I'm finished.
So when my class that wraps the connection is ready for garbage collection, I
close the connection in the destructor. It is as follows...

~CDB()
{
if (this.m_conn.State == System.Data.ConnectionState.Open)
{
try
{
this.m_conn.Close();
}
catch(Exception e)
{
Console.WriteLine(e.Message);
Console.ReadLine(); // I add this just so I can see the message.
}
}
}

The problem is I always receive the exception -- which is an
InvalidOperationException -- "Handle is not initialized." Any ideas what I
am doing wrong, or how to rectify the situation? Thank you. Should you need
more of my code, please do not hesistate to ask. I just thought the other
code was irrelevant in this situation. Thank you again.


Trecius
 
Now, I'm a little confused. So you're all stating that I must ALWAYS call
the Dispose() method everytime I use my class? I'm still new to C#, but it's
impossible to create a class that can dispose of itself? What about
instances where the programmer forgets to call Dispose() on the object
they're using. In this case, the Close() method will never be called. I
suppose this is the crux of the problem, and it's my question. How can I
create my class that will automatically call Close() when the object goes out
of scope and needs to be garbage collected. Thank you.


Trecius
 
Trecius said:
Hello, Newsgroupians:

I am creating a wrapper for (I)DbConnection. I can connect to a database
and place queries; however, I'm having some problems with my wrapped class.

In short, I have the following...

public class CDB
{
protected System.Data.IDbConnection m_conn;

...

}

Now, I've read that I should ALWAYS close my connection when I'm finished.
So when my class that wraps the connection is ready for garbage collection, I
close the connection in the destructor.

..NET doesn't have destructors. That is a finalizer, and it doesn't work
the same as a destructor. The finalizer doesn't run when the object goes
out of scope, as a destructor does in a system that uses reference
counting. When the garbage collector is about to collect the object,
it's placed in a queue of objects that needs finalizing. A background
thread is going through the queue and calls the finalizer in each
object. The fact that the finalizer is run in a different thread might
be the reason for the error that you are getting.

A finalizer can not be used to control the life cycle of an object, as
you have no control over when the finalizer is run.
It is as follows...

~CDB()
{
if (this.m_conn.State == System.Data.ConnectionState.Open)
{
try
{
this.m_conn.Close();
}
catch(Exception e)
{
Console.WriteLine(e.Message);
Console.ReadLine(); // I add this just so I can see the message.
}
}
}

The problem is I always receive the exception -- which is an
InvalidOperationException -- "Handle is not initialized." Any ideas what I
am doing wrong, or how to rectify the situation?

You should implement the IDisposable interface, so that you can call the
Dispose method when you are done with the connection, just as the
DbConnection class does.
 
Trecius said:
Now, I'm a little confused. So you're all stating that I must ALWAYS call
the Dispose() method everytime I use my class? I'm still new to C#, but it's
impossible to create a class that can dispose of itself? What about
instances where the programmer forgets to call Dispose() on the object
they're using. In this case, the Close() method will never be called. I
suppose this is the crux of the problem, and it's my question. How can I
create my class that will automatically call Close() when the object goes out
of scope and needs to be garbage collected. Thank you.

using (CDB db = new CDB())
{
// Use db here.
}

The pattern above is used when you instantiate an object that implements
IDisposable. When db goes out of scope then the Dispose method is
automatically called. This is simply compiler short-hand for this:

CDB db;
try
{
db = new CDB();
}
finally
{
db.Dispose();
}

Yes, you must somehow get your Dispose (i.e., Close) method to be called
or you'll run out of resources (like pooled database connections). If a
programmer forgets to use the using statement or the finally statement
then they have written incorrect code.
 
Trecius said:
Now, I'm a little confused. So you're all stating that I must ALWAYS call
the Dispose() method everytime I use my class?
Yes.

I'm still new to C#, but it's
impossible to create a class that can dispose of itself?

Yes. The compiler doesn't add any extra code to handle when objects go
out of scope. As there is no code to handle this, there is no way of
calling a destructor.

For fully managed objects there is no need for any destructor, as the
garbage collector can free all managed objects by itself. It's only when
you class handles unmanaged resources (like a database connection) that
you need to dispose the object in a controlled way.
What about
instances where the programmer forgets to call Dispose() on the object
they're using. In this case, the Close() method will never be called.

A finalizer is usually used as a backup when implementing IDisposable,
so the Close method will be called eventually, but as you have no
control over when this happens, you will still experience problems
sooner or later if you don't call Dispose properly.
I
suppose this is the crux of the problem, and it's my question. How can I
create my class that will automatically call Close() when the object goes out
of scope and needs to be garbage collected.

You can't do that. Nothing happens when an object goes out of scope.
 
If you implement the IDisposable interface, then you can using the
"using" statement, which will call IDisposable for you.

Here's how to implement the IDisposable interface:
http://www.codeproject.com/useritems/idisposable.asp

and here's an example of using the "using" statement. Remember,
connections shouldn't be left open, you should open them, do your
task, then close them (release back to the pool) as soon as possible.


Code:
using (IDbConnection connection =
DbProviderFactories.GetFactory(providerName).CreateConnection())
{
connection.Open();

using (MyDataAdapter adapter = new MyDataAdapter())
{
adapter.Connection = connection;
adapter.Fill(myDataTable);
}
} // IDispose will be called on the connection here, automatically
closing it



Hope this helps.

Ship.
 
Göran Andersson said:
Yes. The compiler doesn't add any extra code to handle when objects go
out of scope. As there is no code to handle this, there is no way of
calling a destructor.

Just a clarification. It doesn't call any destructors (because there
aren't any), but the compiler treats the using statement specially and
does emit code to call an objects Dispose method. You can code the same
thing by hand with a try-finally block, but the compiler will do this
for you if you can use a using statement.
A finalizer is usually used as a backup when implementing IDisposable,
so the Close method will be called eventually, but as you have no
control over when this happens, you will still experience problems
sooner or later if you don't call Dispose properly.

Is a finalizer really a backup to Dispose? I've never heard that before
and question how it could be used that way. I mean, you have no idea
when a finalizer will be called so what can it do of any use since it
will not know the state of any unmanaged resources by the time the
finalizer runs? I don't think I've ever written a finalizer, especially
not one that has anything to do with the IDispose pattern.
You can't do that. Nothing happens when an object goes out of scope.

I'm not sure I understand what you are saying. In this code:

using (CDB db = new CDB()) { ... }

When db goes out of scope, the compiler has emitted code to cause the
object's Dispose method to be called. So he would implement the IDispose
pattern to cause Close (i.e., Dispose) to be called when all the
references to the object have gone out of scope. (Of course, as already
pointed out, the IDispose pattern need not be implemented unless
unmanaged resources are being used by the class.)

Or do you mean that the just because all the references to an object
have gone out of scope, that doesn't mean anything about when the GC
will get around to cleaning up that object?
 
GlennDoten said:
Just a clarification. It doesn't call any destructors (because there
aren't any), but the compiler treats the using statement specially and
does emit code to call an objects Dispose method. You can code the same
thing by hand with a try-finally block, but the compiler will do this
for you if you can use a using statement.

That is correct. To furter clarify this, it's only the object that you
specify in the using clause that is disposed, any other objects that
happen to have the using block as scope doesn't get disposed.

Example:

using (StreamWriter writer = File.CreateText("info.txt)) {
String message = "Hello world.";
writer.Write(message);
}

Here the string message has the using block as scope. Still, only the
StreamWriter will be disposed, but not the string. (Yes, I know that
strings doesn't implement IDisposable, but it's just an example...)
Is a finalizer really a backup to Dispose?

Yes, it's used that way.
I've never heard that before
and question how it could be used that way. I mean, you have no idea
when a finalizer will be called so what can it do of any use since it
will not know the state of any unmanaged resources by the time the
finalizer runs?

The Dispose method will call GC.SuppressFinalize, so the finalizer will
only run if Dispose was not called.

You can check out the example code for the IDisposable interface:

http://msdn2.microsoft.com/en-us/library/system.idisposable.aspx
I don't think I've ever written a finalizer, especially
not one that has anything to do with the IDispose pattern.


I'm not sure I understand what you are saying. In this code:

using (CDB db = new CDB()) { ... }

When db goes out of scope, the compiler has emitted code to cause the
object's Dispose method to be called.

The compiler adds the code at the end of the using block. This has
nothing at all to do with the scope of the variable. If the scope of the
variable is outside the using block, the code is still added at the end
of the using block:

CDB db = new CDB()
using (db) {
...
// Dispose is called here
}
// the db variable is still reachable here
So he would implement the IDispose
pattern to cause Close (i.e., Dispose) to be called when all the
references to the object have gone out of scope.

The Dispose method has to be called explicitly (for example by using
using). It's not called automatically when the object gets unreachable.
(Of course, as already
pointed out, the IDispose pattern need not be implemented unless
unmanaged resources are being used by the class.)

Or do you mean that the just because all the references to an object
have gone out of scope, that doesn't mean anything about when the GC
will get around to cleaning up that object?

I just mean that nothing happens when an object goes out of scope (or to
be more accurate, when the reference variable goes out of scope).
 
Is a finalizer really a backup to Dispose? I've never heard that before
and question how it could be used that way. I mean, you have no idea
when a finalizer will be called so what can it do of any use since it
will not know the state of any unmanaged resources by the time the
finalizer runs? I don't think I've ever written a finalizer, especially
not one that has anything to do with the IDispose pattern.

Yes, a finalizer is very commonly used as a backup of Dispose.
Actually the recommended implementation for Dispose is to create a
virtual protected member Dispose(bool disposing) and call that with
True if called from Dispose and False if called from the Finalizer.

The finalizer version of Dispose(false) is only useful when a class
contains unmanaged resources which have to be freed. Code paths
originating from a finalizer can not call managed objects because the
GC may collect them out of order (and their own finalizers should take
care of their own cleanup anyways).

HTH,

Sam
 
Göran Andersson said:
That is correct. To furter clarify this, it's only the object that you
specify in the using clause that is disposed, any other objects that
happen to have the using block as scope doesn't get disposed.

Example:

using (StreamWriter writer = File.CreateText("info.txt)) {
String message = "Hello world.";
writer.Write(message);
}

Here the string message has the using block as scope. Still, only the
StreamWriter will be disposed, but not the string. (Yes, I know that
strings doesn't implement IDisposable, but it's just an example...)

Agreed. In that case you'd use this:

using (StreamWriter writer = File.CreateText("info.txt))
{
using (string message = "Hello world.")
{
writer.Write(message);
}
}

(Again, as you said, a string is not disposable, but pretend it is.)
The Dispose method will call GC.SuppressFinalize, so the finalizer will
only run if Dispose was not called.

Ah yes, now that you mention that. I forgot about SuppressFinalize.
The compiler adds the code at the end of the using block. This has
nothing at all to do with the scope of the variable. If the scope of the
variable is outside the using block, the code is still added at the end
of the using block:

CDB db = new CDB()
using (db) {
...
// Dispose is called here
}
// the db variable is still reachable here

The code isn't added to the end of the using block, at least not like
that. The compiler automatically emits a finally block. So while "going
out of scope" is not technically correct, what I meant was that the db
variable is *effectively* out of scope once the finally block runs; that
is, the Dispose method has been run on the object once the scope of the
using block ends. I didn't mean to say the object referred to by the db
variable would be eligible for garbage collection after the using block
is finished, just that the Dispose method is guaranteed to have been
called at that point.
The Dispose method has to be called explicitly (for example by using
using). It's not called automatically when the object gets unreachable.

Well, to nit-pick, I would say that using the using statement calls the
Dispose method implicitly.

Again, I hope I haven't given the impression that Dispose is called
somehow once all the references to it go out of scope.
I just mean that nothing happens when an object goes out of scope (or to
be more accurate, when the reference variable goes out of scope).

Except that it may make the object referenced by the variable eligible
to be garbage collected ("may" because other variables may hold
references to the object as well). But as far as Dispose is concerned,
agreed, nothing happens when a variable referencing an object goes out
of scope.

Phew, I think we're saying the same thing!
 
Samuel said:
Yes, a finalizer is very commonly used as a backup of Dispose.
Actually the recommended implementation for Dispose is to create a
virtual protected member Dispose(bool disposing) and call that with
True if called from Dispose and False if called from the Finalizer.

The finalizer version of Dispose(false) is only useful when a class
contains unmanaged resources which have to be freed. Code paths
originating from a finalizer can not call managed objects because the
GC may collect them out of order (and their own finalizers should take
care of their own cleanup anyways).

HTH,

Thanks, Sam. It does help. I have a number of classes that implement the
dispose pattern, and use GC.SuppressFinalizer and all that, just had a
Senior's Moment, I guess.
 
GlennDoten said:
Agreed. In that case you'd use this:

using (StreamWriter writer = File.CreateText("info.txt))
{
using (string message = "Hello world.")
{
writer.Write(message);
}
}

I prefer:

using (StreamWriter writer = File.CreateText("info.txt"),
string message = "Hello world.")
{
}

There are some contexts in which nesting using statements may make more
sense, but assuming the variables are nominally scoped to the same block
logically, the above syntax is preferable to me.

Pete
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Similar Threads

Database Connection 7
DbConnection and Finalizer 3
A class destructor 4
C# and COM Object 2
List with no duplicates 8
SQL Server login failing 11
Deep Copy and '=' 2
System.Threading.Thread Question 2

Back
Top