On Aug 24, 2012, at 11:03 AM, James Lavery <ja...@microsec.co.uk> wrote: > ResultSetConnection does /not/ subclass Java.Lang.Object. It is a plain C# > object.
A plain C# object with a finalizer [0]. You must be VERY CAREFUL when implementing finalizers: http://msdn.microsoft.com/en-us/library/b1yfkh5e(VS.100).aspx#sectionToggle1 > • An object's Finalize method should free any external resources that > the object owns. Moreover, a Finalize method should release only resources > that the object has held onto. The Finalize method should not reference any > other objects. Emphasis on "external," which you should read as "unmanaged types." ResultSet, PreparedStatement, etc. are managed types, and thus their lifetime is controlled by the GC. Also note the last sentence, "The Finalize method should not reference any other objects." FINALIZERS MUST NOT USE GC-CONTROLLED INSTANCES. There is no ordering between finalizer invocation of instances [1]. Consequently, there is NO WAY to ensure that your ResultSetConnection instance is finalized _before_ the held e.g. ResultSet instance. What's probably happening to you is that the ResultSet instance is being finalized before your ResultSetConnection instance, and thus has it's Handle cleared out, so when you later attempt to call Close(), you're calling it on an invalid instance. Again, Don't Do That™. In general, you should avoid finalizers, period, unless you really, _really_ can't avoid them. - Jon [0] It's a "finalizer", not a "destructor": http://www.ecma-international.org/publications/files/ECMA-ST/Ecma-334.pdf §17.12: > [Note: In the previous version of this standard, what is now referred to as a > "finalizer" was called a "destructor". Experience has shown that the term > "destructor" caused confusion and often resulted to incorrect expectations, > especially to programmers knowing C++. In C++, a destructor is called in a > determinate manner, whereas, in C#, a finalizer is not. To get determinate > behavior from C#, one should use Dispose. end note] [1] OK, there is _a_ way to ensure some form of finalizer ordering by using CriticalFinalizerObject [2]. However, this only provides a loose ordering between "normal" finalizable instances and critical finalizable instances -- the critical ones are finalized _after_ the normal ones -- but it does nothing about ordering between instances within the same "category." This is still irrelevant, though, as Mono doesn't implement the "delayed" finalizer semantics for CriticalFinalizerObject. [2] http://msdn.microsoft.com/en-us/library/system.runtime.constrainedexecution.criticalfinalizerobject.aspx _______________________________________________ Monodroid mailing list Monodroid@lists.ximian.com UNSUBSCRIBE INFORMATION: http://lists.ximian.com/mailman/listinfo/monodroid