Starting on C#...

V

Volker Hetzer

Hi!
We are thinking of doing some performance intensive parts
of our application in C#.
However, I'm a bit concerned about this GC stuff.
From my time as C++ programmer it was pretty easy to
use heavy objects that for instance contain a database conenction
and I could be sure that when the function ended, the connection
object executed a proper disconnect.
So, given class B, I could

int f()
{
B MyConnection;
....
return 0;
}

int c()
{
f();
//Here the database is closed again.
}

And there was no way I could forget anything.
How does this work with C#?
Is the GC only used with objects that are created with new?

Lots of Greetings!
Volker
 
A

Andy

The .Net garbage collector will take care of everything for you.

The exception however is a class which implements the IDisposble
interface. If you use such a class, you have to remember to call
Dispose when you are done with it. That is because IDisposbable
classes usually use COM resources, which can't be garbage collected.
For example, a SqlConnection:

using System.Data.SqlClient;

public static class MyTest {
[STAThread]
public static void Main() {
SqlConnection conn;
string connString;

connString = "Initial Catalog=someDb; Data
Source=localhost;Integrated Security=SSPI"

using( conn = new SqlConnection() ) {
conn.ConnectionString = connString;
conn.Open();

// Do some db stuff
}
}
}

The using block will ensure that, no matter what, Dispose will be
called on the object conn. This will ensure the connection to the
database is closed.

For .Net types which don't implement IDisposable, you can be assured
that the garbage collector will get rid of them (eventually) once all
references to an object have gone out of scope. So you don't need to
worry about the string object in the above code; as soon as the
function exits, connString will be put on the collection list, and the
GC will take care of it later.

HTH
Andy
 
G

Guest

One more thing...

I agree with everything Andy said in his response but would add that as a
C++ programmer you are probably accustomed to using a destructor for your
class. That is going to be VERY counter-productive in this case, and in fact
will actually cut your performance something like 75%. You shouldn't be
using a destructor unless ABSOLUTELY necessary, which in this case means you
are dealing with UNmanaged resources.

HTH

WhiteWizard (aka Gandalf)
MCSD.NET, MCAD, MCT
 
J

J.Marsch

If you want to see an example of how this dispose vs. finalizer stuff is
implemented, look at the System.IO.FileStream object.

FileStream is the object that you use for reading/writing a file. Now you
could let the GC handle everything for you, and just let the filestream
object go out of scope when you are finished with it. However, you will run
into some problems, and that's where IDisposable comes in.

For example, you might have a situation where you need for your FileStream
to realease a file handle immediately, instead of holding onto it until the
GC decides to collect it. This is the same problem that you would run into
in COM if your COM object held onto a file handle until its refcount went to
zero.

On the filestream object, you would call Dispose() or Close() (which calls
Dispose()) to cause the filestream to release the file handle immediately.

You can implement IDisposable on your own classes to give your developers a
way to indicate that the object should release its resources immediately.

As WhiteWizard mentioned, Dispose is a different beast from a Finalizer
(destructor syntax in C#). You only want a finalizer if your object is
holding onto unmanaged resources, such as a Handle, or a DC.

Here's a good article on how the GC works:
http://msdn.microsoft.com/msdnmag/issues/1100/gci/

Here's a good series on using the GC efficiently:
Using the GC Efficiently Part 1:
http://blogs.msdn.com/maoni/archive/2004/06/15/156626.aspx
Using the GC Efficiently Part 2:
http://blogs.msdn.com/maoni/archive/2004/09/25/234273.aspx
Using the GC Efficiently Part 3:
http://blogs.msdn.com/maoni/archive/2004/12/19/327149.aspx
Using the GC Efficiently Part 4:
http://blogs.msdn.com/maoni/archive/2005/05/06/415296.aspx
Clearing up some confusion over finalization:
http://blogs.msdn.com/maoni/archive/2004/11/04/252697.aspx
 
V

Volker Hetzer

Andy said:
The .Net garbage collector will take care of everything for you.

The exception however is a class which implements the IDisposble
interface. If you use such a class, you have to remember to call
Dispose when you are done with it. That is because IDisposbable
classes usually use COM resources, which can't be garbage collected.
This will be the normal case for me.
For example, a SqlConnection:

using System.Data.SqlClient;

public static class MyTest {
[STAThread]
public static void Main() {
SqlConnection conn;
string connString;

connString = "Initial Catalog=someDb; Data
Source=localhost;Integrated Security=SSPI"

using( conn = new SqlConnection() ) {
conn.ConnectionString = connString;
conn.Open();

// Do some db stuff
}
}
}

The using block will ensure that, no matter what, Dispose will be
called on the object conn. This will ensure the connection to the
database is closed.
Ok, thanks a lot.
I just saw that for this to work with several objects I've got to
nest the using calls but this is something I can live with. (The advantage
is that I can control the order of the dispose calls.)

Lots of Thanks!
Volker
 

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

Top