.Net Finalizer Order / Semantics in Esent and Ravendb

Posted by mattcodes on Stack Overflow See other posts from Stack Overflow or by mattcodes
Published on 2010-05-21T04:29:59Z Indexed on 2010/05/21 4:40 UTC
Read the original article Hit count: 322

Filed under:
|
|
|
|

Help me understand. I've read that

"The time and order of execution of finalizers cannot be predicted or pre-determined"

Correct?

However looking at RavenDB source code TransactionStorage.cs I see this

~TransactionalStorage()
{
try
{
 Trace.WriteLine(
  "Disposing esent resources from finalizer! You should call TransactionalStorage.Dispose() instead!");
 Api.JetTerm2(instance, TermGrbit.Abrupt);
}
catch (Exception exception)
{
  try
  {
   Trace.WriteLine("Failed to dispose esent instance from finalizer because: " + exception);
   }
   catch
   {
   }
 }
}

The API class (which belongs to Managed Esent) which presumable takes handles on native resources presumably using a SafeHandle?

So if I understand correctly the native handles SafeHandle can be finalized before TransactionStorage which could have undesired effects, perhaps why Ayende has added an catch all clause around this?

Actually diving into Esent code, it does not use SafeHandles.

According to CLR via C# this is dangerous?

    internal static class SomeType {  
   [DllImport("Kernel32", CharSet=CharSet.Unicode, EntryPoint="CreateEvent")]  

 // This prototype is not robust  
   private static extern IntPtr CreateEventBad( 
      IntPtr pSecurityAttributes, Boolean manualReset, Boolean initialState, String name);  


 // This prototype is robust  
  [DllImport("Kernel32", CharSet=CharSet.Unicode, EntryPoint="CreateEvent")]  
  private static extern SafeWaitHandle CreateEventGood( 
     IntPtr pSecurityAttributes, Boolean manualReset, Boolean initialState, String name)

  public static void SomeMethod() {  
     IntPtr         handle = CreateEventBad(IntPtr.Zero, false, false, null);  
     SafeWaitHandle swh    = CreateEventGood(IntPtr.Zero, false, false, null);  
  }  
}

Managed Esent (NativeMEthods.cs) looks like this (using Ints vs IntPtrs?):

  [DllImport(EsentDll, CharSet = EsentCharSet, ExactSpelling = true)]
    public static extern int JetCreateDatabase(IntPtr sesid, string szFilename, string szConnect, out uint dbid, uint grbit);

Is Managed Esent handling finalization/dispoal the correct way, and second is RavenDB handling finalizer the corret way or compensating for Managed Esent?

© Stack Overflow or respective owner

Related posts about esent

Related posts about ravendb