Libor Theimer

Libor Theimer

  • NA
  • 32
  • 7.4k

Wanted GC guru

Jun 17 2014 7:00 PM
Hi,
I found the attached example (classes are not complete, but enough for explanation):

public class RegistryKey : IDisposable
{
  ...
  [DllImport("advapi32.dll", CharSet=CharSet.Auto)]
  static extern int RegDeleteKey(IntPtr hKey, string lpSubKey);
 
  public void DeleteSubKey(string subKey)
  {
  // Delete the subkey
  int result = RegDeleteKey(hKey, subKey);
  if (result != 0)
  throw new ApplicationException("Could not delete registry key: " +
  ErrorHelper.GetErrorMessage(result));
  }
}

A C# client might use this as follows:

public class Client
{
  static readonly IntPtr HKEY_LOCAL_MACHINE =
  new IntPtr(unchecked((int)0x80000002));
 
  public static void Main()
  {
  RegistryKey key =
  new RegistryKey(HKEY_LOCAL_MACHINE, "SOFTWARE\\.NET and COM");
  key.DeleteSubKey("TemporaryKey");
  }
}

with this comment:
The call to DeleteSubKeyis the last time the RegistryKeyinstance is used, and the implementation of DeleteSubKeycalls a PInvoke method with parameter types that don't keep the object alive (a simple by-value IntPtrand string). Therefore, there's a rare chance that the call to DeleteSubKey will cause an exception to be thrown. Right before the PInvoke call to RegDeleteKey, the garbage collector could free the RegistryKeyinstance because there's no further use of it anywhere in the program. (Had thisbeen passed to a PInvoke method, the instance would not be eligible for collection.) If this happens, and if the object's finalizer runs beforeRegDeleteKeyuses the HKEYpassed to it, an ApplicationExceptionwould be thrown with the message, "The handle is invalid," due to the finalizer's call to RegCloseKey.

And question is: is it possible for GC to free obj. instance inside the method of the same instance? If yes, is it the same in vb.net?

It's pretty crazy, I think...

Answers (10)