On 27 April 2012 11:39, Larry Brasfield <larry_brasfi...@iinet.com> wrote:

>
> When you use a collection of native code from managed code, and when that
> native code has cleanup to do, defined by its own conventions rather than
> the conventions established for the managed code system, you cannot count
> on garbage collection to get the job done.  In addition to memory
> allocations, there are likely to be on-disk data and files that need to be
> brought to a proper state when SQLite's designed close/exit mechanisms are
> invoked.  You "works as it should" is only assured (inasmuch as any
> software can) when you use the .Net framework's assured disposition
> mechanism ("using ..." and properly implemented IDispose) or effect the
> equivalent in your own code.
>
> Yes thanks I'm familiar with using native resources from .net.  After much
more debugging I have found what I think is a bug.  Some how
SQLiteConnectionHandle is finalized but the weak reference.target returned
from the pool is not null.  Instead the weak reference returns a
SQLiteConnectionHandle that has had Finalize called but the
weakreference.IsAlive is true and the target is not null.  I don't get it
but that's what is happening. Our db code is sloppy so I'm not ruling out
something we have done.  However below I provide some code which will
prevent the AccessViolationException exception and allow the application to
function normally.


>
>  So is this intended behaviour or a bug?  I can try to come up with a test
>> case that reproduces this if needed.
>>
>
> It's not really intended behavior but intent cannot cure this problem
> unless SQLite's finalizing API is used.
>
>
I'm not sure I follow you.  Users of System.Data.SQLite shouldn't have to
concern themselves with calling dispose.  Regardless of that, even if you
do call dispose on the SQLiteConnection instance explicitly (or through a
using statement) the underlying SQLiteConnectionHandle is added to the
pool, where it can be garbage collected before it is removed.  I was wrong
when I said in my first post that this only happened when I let the
connection be implicitly garbage collected.  This would appear to be a
problem with any SQLiteConnectionHandle added to the pool.  I think the
only reason our code exposed this is that we had many
SQLiteConnectionHandle end up in the pool over a long period of time so the
garbage collector hand a chance to run on those SQLiteConnectionHandle.

For Joe:

Anyway I've added the following code:

in UnsafeNativeMethods.cs method ReleaseHandle() add

handle = IntPtr.Zero;
after  SQLiteBase.CloseConnection(this);  (I'd move the trace statement to
the beginning of the function...)

In SQLConnectionPool.cs, method Remove() approximately line 80 check for
both null and !IsInvalid
if (hdl != null && !hdl.IsInvalid)
          {
            return hdl;
          }

This way it's impossible for the pool to return an invalid handle.  With
these changes our application runs without problems with pooling on.

FWIW Our application performs all db access in a single thread, the main
application thread.  So I don't think it has to do with threads.  I had
started on a coming up with a test case, I'll try to finish it and see if I
can reproduce it outside of our application.

Thanks
Greg.
_______________________________________________
sqlite-users mailing list
sqlite-users@sqlite.org
http://sqlite.org:8080/cgi-bin/mailman/listinfo/sqlite-users

Reply via email to