Home | Contact Us | FAQ | Search & Site Map | Link to Us
Sign In | Join | Other 45 Sites in Network
HomeAnnouncementsFree MagazinesWhite PapersSubmit Content
Discussion GroupsASP.NETWindows FormsLanguages.NET FrameworkVisual Studio.NET
Articles.NET FrameworkASP.NETToolsWindows Forms
.NET DirectoryOpen Source ProjectsUser GroupsWeb Resources
Related Topics
Visual Basic 6SQL ServerMS AccessOther DB ProductsMS Server ProductsMore Topics ...

.NET Forum / Languages / C# / August 2007

Tip: Looking for answers? Try searching our database.

DbConnection

Thread view: 
Enable EMail Alerts  Start New Thread
Thread rating: 
Trecius - 15 Aug 2007 18:52 GMT
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
Adrian Voicu - 15 Aug 2007 21:14 GMT
Which part of the code throws the exception? When you check the connection
status or when you try to close the connection?

Adrian.
Signature

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

> Hello, Newsgroupians:
>
[quoted text clipped - 38 lines]
>
> Trecius
Trecius - 15 Aug 2007 21:42 GMT
The method that is creating the exception is this.m_conn.Close().

Trecius

> Which part of the code throws the exception? When you check the connection
> status or when you try to close the connection?
[quoted text clipped - 43 lines]
> >
> > Trecius
Nicholas Paldino [.NET/C# MVP] - 15 Aug 2007 21:33 GMT
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

Signature

         - Nicholas Paldino [.NET/C# MVP]
         - mvp@spam.guard.caspershouse.com

> Hello, Newsgroupians:
>
[quoted text clipped - 42 lines]
>
> Trecius
Samuel R. Neff - 15 Aug 2007 21:39 GMT
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

------------------------------------------------------------
We're hiring!  B-Line Medical is seeking .NET
Developers for exciting positions in medical product
development in MD/DC.  Work with a variety of technologies
in a relaxed team environment.  See ads on Dice.com.

>Hello, Newsgroupians:
>
[quoted text clipped - 12 lines]
>
>Trecius
Trecius - 15 Aug 2007 23:44 GMT
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

> Don't use a finalizer.  Make your class implement IDisposable and in
> Dispose() call Close() on the connection.  Any time your custom class
[quoted text clipped - 31 lines]
> >
> >Trecius
GlennDoten - 16 Aug 2007 00:05 GMT
> 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
[quoted text clipped - 4 lines]
> 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.

Signature

-glenn-

Göran Andersson - 16 Aug 2007 00:12 GMT
> 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.

Signature

Göran Andersson
_____
http://www.guffa.com

Barney - 16 Aug 2007 10:51 GMT
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.

On Aug 16, 12:12 am, G?ran Andersson <gu...@guffa.com> wrote:
> > Now, I'm a little confused.  So you're all stating that I must ALWAYS call
> > the Dispose() method everytime I use my class?
[quoted text clipped - 32 lines]
> G?ran Andersson
> _____http://www.guffa.com
GlennDoten - 16 Aug 2007 12:40 GMT
>> 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.

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.

>> What about instances where the programmer forgets to call Dispose() on
>> the object they're using.  In this case, the Close() method will never
[quoted text clipped - 4 lines]
> 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.

>> 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.

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?

Signature

-glenn-

Göran Andersson - 16 Aug 2007 13:59 GMT
>>> I'm still new to C#, but it's impossible to create a class that can
>>> dispose of itself?
[quoted text clipped - 8 lines]
> 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...)

>>> What about instances where the programmer forgets to call Dispose()
>>> on the object they're using.  In this case, the Close() method will
[quoted text clipped - 6 lines]
>
> 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.
[quoted text clipped - 11 lines]
> 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
[quoted text clipped - 3 lines]
> 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).

Signature

Göran Andersson
_____
http://www.guffa.com

GlennDoten - 16 Aug 2007 14:20 GMT
>>>> I'm still new to C#, but it's impossible to create a class that can
>>>> dispose of itself?
[quoted text clipped - 23 lines]
> 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.)

>> 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
[quoted text clipped - 3 lines]
> 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.

>>>> 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
[quoted text clipped - 20 lines]
> }
> // 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.

>> 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.

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.

>> 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).

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!

Signature

-glenn-

Peter Duniho - 16 Aug 2007 17:56 GMT
> Agreed. In that case you'd use this:
>
[quoted text clipped - 5 lines]
>     }
> }

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
Samuel R. Neff - 16 Aug 2007 14:06 GMT
>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

------------------------------------------------------------
We're hiring!  B-Line Medical is seeking .NET
Developers for exciting positions in medical product
development in MD/DC.  Work with a variety of technologies
in a relaxed team environment.  See ads on Dice.com.
GlennDoten - 16 Aug 2007 14:25 GMT
>> 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
[quoted text clipped - 15 lines]
>
> 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.

Signature

-glenn-

Göran Andersson - 15 Aug 2007 23:47 GMT
> Hello, Newsgroupians:
>
[quoted text clipped - 14 lines]
> 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...
>
[quoted text clipped - 17 lines]
> 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.

Signature

Göran Andersson
_____
http://www.guffa.com


Free Magazines

Get these publications absolutely FREE for up to 12 months. There are no hidden fees and no obligation. Simply choose a title, complete the application form and submit it. Read more ...

Oracle MagazineNetwork ComputingComputer WorldBio-IT WorldeWeekInformation WeekInfosecurity
 
Sign In
Join
My Latest Posts
My Monitored Threads
My Blog
My Photo Gallery
My Profile
My Homepage

Start New Thread
Enable EMail Alerts
Rate this Thread



©2008 Advenet LLC   Privacy Policy - Terms of Use
This website includes both content owned or controlled by Advenet as well as content owned or controlled by third parties.