Index: System.Data.SQLite/SQLiteConnectionPool.cs ================================================================== --- System.Data.SQLite/SQLiteConnectionPool.cs +++ System.Data.SQLite/SQLiteConnectionPool.cs @@ -111,30 +111,30 @@ /// /// Attempt to pull a pooled connection out of the queue for active duty /// /// The filename for a desired connection - /// The maximum size the connection pool for the filename can be - /// The pool version the returned connection will belong to - /// Returns NULL if no connections were available. Even if none are, the poolversion will still be a valid pool version + /// The maximum size the connection pool for the filename can be + /// The pool version the returned connection will belong to + /// Returns NULL if no connections were available. Even if none are, the poolversion will still be a valid pool version internal static SQLiteConnectionHandle Remove(string fileName, int maxPoolSize, out int version) { lock (_connections) { Pool queue; - // Default to the highest pool version + // Default to the highest pool version version = _poolVersion; // If we didn't find a pool for this file, create one even though it will be empty. // We have to do this here because otherwise calling ClearPool() on the file will not work for active connections // that have never seen the pool yet. if (_connections.TryGetValue(fileName, out queue) == false) { queue = new Pool(_poolVersion, maxPoolSize); - _connections.Add(fileName, queue); - + _connections.Add(fileName, queue); + return null; } // We found a pool for this file, so use its version number version = queue.PoolVersion; @@ -146,19 +146,21 @@ Queue poolQueue = queue.Queue; if (poolQueue == null) return null; while (poolQueue.Count > 0) { - WeakReference cnn = poolQueue.Dequeue(); + WeakReference cnn = poolQueue.Dequeue(); + if (cnn == null) continue; SQLiteConnectionHandle hdl = cnn.Target as SQLiteConnectionHandle; if ((hdl != null) && !hdl.IsClosed && !hdl.IsInvalid) { - Interlocked.Increment(ref _poolOpened); + Interlocked.Increment(ref _poolOpened); return hdl; } + cnn.Target = null; GC.KeepAlive(hdl); - } + } return null; } } /// @@ -176,16 +178,18 @@ Queue poolQueue = pair.Value.Queue; while (poolQueue.Count > 0) { - WeakReference cnn = poolQueue.Dequeue(); + WeakReference cnn = poolQueue.Dequeue(); + if (cnn == null) continue; SQLiteConnectionHandle hdl = cnn.Target as SQLiteConnectionHandle; if (hdl != null) { hdl.Dispose(); } + cnn.Target = null; GC.KeepAlive(hdl); } // Keep track of the highest revision so we can go one higher when we're finished if (_poolVersion <= pair.Value.PoolVersion) @@ -216,16 +220,18 @@ Queue poolQueue = queue.Queue; if (poolQueue == null) return; while (poolQueue.Count > 0) { - WeakReference cnn = poolQueue.Dequeue(); + WeakReference cnn = poolQueue.Dequeue(); + if (cnn == null) continue; SQLiteConnectionHandle hdl = cnn.Target as SQLiteConnectionHandle; if (hdl != null) { hdl.Dispose(); } + cnn.Target = null; GC.KeepAlive(hdl); } } } } @@ -279,16 +285,18 @@ Queue poolQueue = queue.Queue; if (poolQueue == null) return; while (poolQueue.Count > target) { - WeakReference cnn = poolQueue.Dequeue(); + WeakReference cnn = poolQueue.Dequeue(); + if (cnn == null) continue; SQLiteConnectionHandle hdl = cnn.Target as SQLiteConnectionHandle; if (hdl != null) { hdl.Dispose(); } + cnn.Target = null; GC.KeepAlive(hdl); } } } }