When do I need to use GC.KeepAlive?

It’s very unintuitive, but the runtime can decide that an object is garbage much sooner than you expect. More specifically, an object can become garbage while a method is executing on the object, which is contrary to most developers’ expectations. Chris Brumme explains the issue on his blog. I’ve taken Chris’s code and expanded it into a full app that you can play with if you want to prove to yourself that this is a real problem:

using System;

using System.Runtime.InteropServices;

class Win32

{

[DllImport("kernel32.dll")]

public static extern IntPtr CreateEvent( IntPtr lpEventAttributes,

bool bManualReset,bool bInitialState, string lpName);

[DllImport("kernel32.dll", SetLastError=true)]

public static extern bool CloseHandle(IntPtr hObject);

[DllImport("kernel32.dll")]

public static extern bool SetEvent(IntPtr hEvent);

}

class EventUser

{

public EventUser()

{

hEvent = Win32.CreateEvent( IntPtr.Zero, false, false, null );

}

~EventUser()

{

Win32.CloseHandle( hEvent );

Console.WriteLine("EventUser finalized");

}

public void UseEvent()

{

UseEventInStatic( this.hEvent );

}

static void UseEventInStatic( IntPtr hEvent )

Satish Marwat Dot Net Web Resources satishcm@gmail.com 12 Page

{

//GC.Collect();

bool bSuccess = Win32.SetEvent( hEvent );

Console.WriteLine( "SetEvent " + (bSuccess ? "succeeded" : "FAILED!") );

}

IntPtr hEvent;

}

class App

{

static void Main(string[] args)

{

EventUser eventUser = new EventUser();

eventUser.UseEvent();

}

}

If you run this code, it'll probably work fine, and you'll get the following

output:

SetEvent succeeded

EventDemo finalized

However, if you uncomment the GC.Collect() call in the UseEventInStatic()

method, you'll get this output:

EventDemo finalized

SetEvent FAILED!