On Aug 24, 2012, at 9:15 AM, James Lavery <ja...@microsec.co.uk> wrote:
> What we've found is that as soon as a GC_EXPLICIT is triggered, we're getting 
> "Object reference not set to an instance of an object" errors and the system 
> crashes.

You mention GC_EXPLICIT, then show code that's calling Close(). I'm slightly 
confused. :-)

> The device log shows the following at the same time:

Is there any other output before the stack trace in the `adb logcat` output? 
Perhaps something from Dalvik?

> 08-24 13:58:51.621 I/mono    (12463): Stacktrace:
> 08-24 13:58:51.621 I/mono    (12463): 
> 08-24 13:58:51.621 I/mono    (12463):   at 
> Android.Runtime.JNIEnv.CallVoidMethod (intptr,intptr)
> 08-24 13:58:51.621 I/mono    (12463):   at 
> Com.Ianywhere.Ultralitejni12.IResultSetInvoker.Close ()
> 08-24 13:58:51.621 I/mono    (12463):   at 
> Autoforms.Universal.Mobile.Droid.DAO.ResultSetConnection.Close ()
> 08-24 13:58:51.621 I/mono    (12463):   at 
> Autoforms.Universal.Mobile.Droid.DAO.ResultSetConnection.Finalize ()
> 08-24 13:58:51.621 I/mono    (12463):   at (wrapper runtime-invoke) 
> object.runtime_invoke_virtual_void__this__ (object,intptr,intptr,intptr)

This is very interesting; Close() is being called from Finalize().

Does your ResultSetConnection class provide a finalizer? Does it also subclass 
Java.Lang.Object?

Java.Lang.Object subclasses MUST NOT provide a finalizer; override 
Java.Lang.Object.Dispose(bool disposing) instead. Furthermore, as with the 
normal IDisposable pattern, managed objects MUST NOT be referenced when 
`disposing` is false, as those instances may have already been finalized:

        partial class ResultSetConnection {

                protected override void Dispose (bool disposing)
                {
                        if (disposing) {
                                ResultSet.Close();
                                ResultSet.Dispose();
            
                                PreparedStatement.Close();
                                PreparedStatement.Dispose();

                                Connection.Release();
                                Connection.Dispose();
                        }
                }

                public void Close ()
                {
                        if (Handle == IntPtr.Zero)
                                return;
                        base.Dispose ();
                }
        }

The above makes Close() a synonym for Dispose(), invalidating the instance 
(which may or may not be appropriate for you, but is generally consistent with 
the BCL, e.g. System.IO.Stream [0]).

 - Jon

[0] 
https://github.com/mono/mono/blob/master/mcs/class/corlib/System.IO/Stream.cs#L98

_______________________________________________
Monodroid mailing list
Monodroid@lists.ximian.com

UNSUBSCRIBE INFORMATION:
http://lists.ximian.com/mailman/listinfo/monodroid

Reply via email to