diff --git a/src/Microsoft.Data.Sqlite.Core/SqliteConnectionPool.cs b/src/Microsoft.Data.Sqlite.Core/SqliteConnectionPool.cs index e4dd55a2566..9f78f7f7162 100644 --- a/src/Microsoft.Data.Sqlite.Core/SqliteConnectionPool.cs +++ b/src/Microsoft.Data.Sqlite.Core/SqliteConnectionPool.cs @@ -5,6 +5,7 @@ using System.Collections.Concurrent; using System.Collections.Generic; using System.Diagnostics; +using System.Linq; using System.Threading; namespace Microsoft.Data.Sqlite @@ -157,17 +158,17 @@ private bool ReclaimLeakedConnections() { var leakedConnectionsFound = false; + List leakedConnections; lock (_connections) { - foreach (var connection in _connections) - { - if (connection.Leaked) - { - Return(connection); + leakedConnections = _connections.Where(c => c.Leaked).ToList(); + } - leakedConnectionsFound = true; - } - } + foreach (var connection in leakedConnections) + { + leakedConnectionsFound = true; + + Return(connection); } return leakedConnectionsFound; diff --git a/test/Microsoft.Data.Sqlite.Tests/SqliteConnectionFactoryTest.cs b/test/Microsoft.Data.Sqlite.Tests/SqliteConnectionFactoryTest.cs index 764f5766b23..ddb65e0edab 100644 --- a/test/Microsoft.Data.Sqlite.Tests/SqliteConnectionFactoryTest.cs +++ b/test/Microsoft.Data.Sqlite.Tests/SqliteConnectionFactoryTest.cs @@ -4,6 +4,7 @@ using System; using System.Data; using System.IO; +using System.Runtime.CompilerServices; using SQLitePCL; using Xunit; @@ -218,6 +219,26 @@ public void EnableExtensions_doesnt_bleed_across_connections() Assert.Equal(disabledMessage, ex.Message); } + [Fact] + public void Clear_works_when_connection_leaked() + { + using var connection = new SqliteConnection(ConnectionString); + connection.Open(); + + LeakConnection(); + GC.Collect(); + + SqliteConnection.ClearPool(connection); + + [MethodImpl(MethodImplOptions.NoInlining)] + static void LeakConnection() + { + // Don't add using! + var connection = new SqliteConnection(ConnectionString); + connection.Open(); + } + } + public void Dispose() { SqliteConnection.ClearAllPools();