Click here to Skip to main content
13,865,159 members
Click here to Skip to main content
Add your own
alternative version


26 bookmarked
Posted 2 Mar 2004

GC 102

, 2 Mar 2004
Rate this:
Please Sign up or sign in to vote.
Further notes on programming for the Garbage Collector.


In GC 101,  I discussed the reasons for Finalize and Dispose, and how to implement these methods in your components. The C# language has some nice built-in functionality to help you with the Disposing pattern, which I will discuss here.

Cool C# feature: using

Consider the following code:

SqlConnection cn = new SqlConnection(cnString);
//Use the open connection

If an exception had to be thrown on the call to Open, Dispose will never get called, and your resource might leak. I'm sure you already know the solution:

    SqlConnection cn = new SqlConnection(cnString);
    //Use the open connection

This code does exactly what the first listing does, but is safer - you are guaranteed that Dispose will be called. But, it is also much less readable! C# has a nice feature to help with readability here: the using clause. Our code can be rewritten as:

using (SqlConnection cn = new SqlConnection(cnString))
    //Use the open connection

Lovely, isn’t it? As soon as the using block exits, Dispose will automatically be called on all objects that implement IDisposable and are created with the using-clause. If you look at the compiler-generated IL, you will see that a try - finally is actually implemented.

Cool C# feature: foreach

You might have collections of expensive (disposable) objects from time to time. To ease coding against your collection, have it implement IDisposable:

internal class openDBConnectionsEnumerator : IEnumerator, IDisposable

public class openDBConnections : IEnumerable
    public IEnumerator GetEnumerator()
        return new openDBConnectionsEnumerator();

Now, you can use your collection in a foreach loop, and Dispose is called automatically on your collection when the loop exits:

OpenDBConnections cons = new OpenDBConnections();
foreach(DBConnection in cons)
    //Do something with connection object
} //Dispose is called on the IEnumerator when loop exits

Performance issues

The GC has only one thread that calls Finalize on all the objects in the finalization queue, and thus might have a tough time in keeping up with Finalizable objects created by more than one user thread. A shortened overview of a Finalizable object’s lifespan:

There are actions here that impacts negatively on performance:

  1. Enlisting in the Finalization queue
  2. Removing from Finalization queue to be enlisted in To Be Finalized queue
  3. Calling Finalize on the component
  4. Removing from To Be Finalized queue

It should be obvious that, if possible, the shortcut should be taken, and Finalizable components avoided. To do so, and this is quite important:

  1. Don’t create Finalizers (or destructors) for your components unless absolutely necessary.
  2. For components where you do need a destructor, always call Dispose on your component when appropriate. This suppresses the GC's call to Finalize and saves you the overhead of calling Finalize and enlisting in the To Be Finalized queue.


A component’s Dispose(bool) method should never be called from both the GC’s finalizer thread and a user thread. There may be instances where more than one user thread calls the method. In this case, make your cleanup code thread safe in exactly the same way you’d make any code thread safe. If you are 100% sure that your code will not be called by more than one user thread at a time, don’t enforce thread-safety, as this impacts negatively on performance.

(You will also find this article on my blog).


This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here


About the Author

Ernst Kuschke
Web Developer
South Africa South Africa
Ernst develops software for the agricultural industry.
He moderates the SADeveloper INETA community, and gives talks on development-related stuff from time to time.
He is an MVP in Visual C#, but whilst he advocates the adoption of .NET, he is also skilled in non-Microsoft technologies.
Sometimes he chats about it.

You may also be interested in...

Comments and Discussions

GeneralIncorrect code example Pin
Staffan O9-Mar-04 22:34
memberStaffan O9-Mar-04 22:34 
GeneralRe: Incorrect code example Pin
Ernst Kuschke10-Mar-04 20:55
memberErnst Kuschke10-Mar-04 20:55 
GeneralRe: Incorrect code example Pin
dzCepheus14-Mar-04 20:40
memberdzCepheus14-Mar-04 20:40 
Generalforeach does not call Dispose on collection, but on enumerator Pin
Frank Hileman9-Mar-04 4:28
memberFrank Hileman9-Mar-04 4:28 
GeneralRe: foreach does not call Dispose on collection, but on enumerator Pin
Ernst Kuschke21-Apr-04 9:29
memberErnst Kuschke21-Apr-04 9:29 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

Permalink | Advertise | Privacy | Cookies | Terms of Use | Mobile
Web03 | 2.8.190214.1 | Last Updated 3 Mar 2004
Article Copyright 2004 by Ernst Kuschke
Everything else Copyright © CodeProject, 1999-2019
Layout: fixed | fluid