Hi Edd, Please check out the GC.SuppressFinalize function.
Matthijs ter Woord ----- Original Message ----- From: "Edd Dumbill" <[EMAIL PROTECTED]> To: <[email protected]> Sent: Tuesday, January 04, 2005 5:42 PM Subject: [Mono-list] Problem with Dispose() and unmanaged resources > Hi, > > In Redland# we use the pattern described by Microsoft for using > IDisposable to wrap unmanaged resources, described here: > http://makeashorterlink.com/?Y3861282A > > I have a private member of type IntPtr set to the unmanaged resource, > and a P/Invoke to a cleanup C function is made in the Dispose call, and > then the member set to IntPtr.Zero, as described under "Implementing a > Dispose method". > > The problem is that -- when Dispose is run from the Finalizer (that is, > Dispose wasn't called before the object was GC'd) -- it seems the IntPtr > member has already been finalized, and there's a NullReferenceException > generated. Under Mono 1.0.4 this prints out: > > Unhandled Exception: System.NullReferenceException: Object reference not > set to an instance of an object > > And then the runtime hangs. This happens only occasionally, and less > frequently if I'm generating trace output. > > Many of the traced sessions look a bit like this: > > ENTER: (wrapper runtime-invoke) System.Object:runtime_invoke_void > (object,intptr,intptr,intptr)([Redland.Serializer:0x8096a90], (nil), > 0xb6a659c8, 0xb619e2a0, ). ENTER: Redland.Serializer:Finalize > ()(this:0x8096a90[Redland.Serializer test.exe], ) > . . ENTER: Redland.Serializer:Dispose > (bool)(this:0x8096a90[Redland.Serializer test.exe], 0, ) > . . . ENTER: (wrapper managed-to-native) > Redland.Serializer:librdf_free_serializer (intptr)(0x8172ba8, ) > . . . . ENTER: (wrapper runtime-invoke) > System.Object:runtime_invoke_void > (object,intptr,intptr,intptr)([System.NullReferenceException:0x8098c90], > (nil), (nil), 0xb619e3b0, ) > . . . . . ENTER: System.NullReferenceException:.ctor > ()(this:0x8098c90[System.NullReferenceException test.exe], ) > . . . . . . ENTER: Locale:GetText (string)([STRING:0x8111c78:A null > value was found where an object instance was required.], ) > . . . . . . LEAVE: Locale:GetText (string)[STRING:0x8111c78:A null value > was found where an object instance was required.] > . . . . . LEAVE: System.NullReferenceException:.ctor () > . . . . LEAVE: (wrapper runtime-invoke) > System.Object:runtime_invoke_void > (object,intptr,intptr,intptr)[OBJECT:(nil)] > EXCEPTION handling: NullReferenceException > EXCEPTION: finally clause 0 of Redland.Serializer:Finalize () > . . . . ENTER: System.Object:Finalize > ()(this:0x8096a90[Redland.Serializer test.exe], ) > . . . . LEAVE: System.Object:Finalize () > EXCEPTION: catch found at clause 0 of (wrapper runtime-invoke) > System.Object:runtime_invoke_void (object,intptr,intptr,intptr) > > What I see happening above is the NullReferenceException being thrown > when it attempts to pass the value of the private IntPtr to the C > cleanup function, librdf_free_serializer(). > > I pulled Mono SVN HEAD to see if things worked any different there. The > good news is that we no longer seem to get the random hangs that 1.0.4 > generates, but the trace shows that the NullReferenceException thing is > still happening. At the best, this means memory leaks are going to > happen. > > Have I got something wrong here, or is there a bug with finalizing > classes? The code is structured just the way the MSDN example suggests. > > -- Edd > > > _______________________________________________ > Mono-list maillist - [email protected] > http://lists.ximian.com/mailman/listinfo/mono-list > _______________________________________________ Mono-list maillist - [email protected] http://lists.ximian.com/mailman/listinfo/mono-list
