While creating the 3rd Edition of my CLR via C# book (http://www.amazon.com/CLR-via-C-Third-Pro-Developer/dp/0735627045/ref=dp_ob_title_bk), I came up with a cool little class that will raise an event after a collection of Generation 0 or Generation 2 occurs. Here is the code for the class:

public static class GCNotification {
  
private static Action<Int32> s_gcDone = null; // The event’s field
  
public static event Action<Int32> GCDone {
     
add {
        
// If there were no registered delegates before, start reporting notifications now 
        
if (s_gcDone == null) { new GenObject(0); new GenObject(2); }
         s_gcDone +=
value;
      }
     
remove { s_gcDone -= value; }
   }
  
private sealed class GenObject {
     
private Int32 m_generation;
     
public GenObject(Int32 generation) { m_generation = generation; }
      ~GenObject() {
// This is the Finalize method
        
// If this object is in the generation we want (or higher), 
        
// notify the delegates that a GC just completed
        
if (GC.GetGeneration(this) >= m_generation) {
           
Action<Int32> temp = Interlocked.CompareExchange(ref s_gcDone, null, null);
           
if (temp != null) temp(m_generation);
         }
         // Keep reporting notifications if there is at least one delegate
        
// registered, the AppDomain isn’t unloading, and the process 
        
// isn’t shutting down
        
if ((s_gcDone != null) && 
            !
AppDomain.CurrentDomain.IsFinalizingForUnload() && 
            !
Environment.HasShutdownStarted) {
           
// For Gen 0, create a new object; for Gen 2, resurrect the
           
// object & let the GC call Finalize again the next time Gen 2 is GC’d
           
if (m_generation == 0) new GenObject(0);
            
else GC.ReRegisterForFinalize(this);
         }
else { /* Let the objects go away */ }
      }
   }
}

And here is some code to see it in action:

public static void Main() {
  
GCNotification.GCDone += g => Console.Beep(g == 0 ? 800 : 8000, 200);
  
var l = new List<Object>();
  
// Construct a lot of 100-byte objects.
  
for (Int32 x = 0; x < 1000000; x++) {
     
Console.WriteLine(x);
     
Byte[] b = new Byte[100];
      l.Add(b);
   }
}

 

This gives you a very small taste of what you should expect to see in the next edition of my book. Hope you enjoy.