Mám podezření, že toto je ten problém, na konci metody:
this.connectionPool.Putback(sqlConnection);
Pouze berete dva prvky z iterátoru - takže nikdy nedokončíte while
smyčka, pokud ve skutečnosti není ze čtečky vrácena pouze jedna hodnota. Nyní používáte LINQ, který bude automaticky volat Dispose()
na iterátoru, takže using
výpis bude stále likvidovat čtečku - ale nevrátíte připojení zpět do fondu. Pokud to uděláte v finally
blok, myslím, že budeš v pořádku:
var sqlConnection = this.connectionPool.Take();
try
{
// Other stuff here...
using (var reader = this.selectWithSourceVectorCommand.ExecuteReader())
{
while (reader.Read())
{
yield return ReaderToVectorTransition(reader);
}
}
}
finally
{
this.connectionPool.Putback(sqlConnection);
}
Nebo v ideálním případě, pokud je váš fond připojení vaší vlastní implementací, proveďte Take
vrátit něco, co implementuje IDisposable
a po dokončení vrátí připojení zpět do fondu.
Zde je krátký, ale kompletní program, který demonstruje, co se děje, bez jakýchkoli skutečných databází:
using System;
using System.Collections.Generic;
using System.Linq;
class DummyReader : IDisposable
{
private readonly int limit;
private int count = -1;
public int Count { get { return count; } }
public DummyReader(int limit)
{
this.limit = limit;
}
public bool Read()
{
count++;
return count < limit;
}
public void Dispose()
{
Console.WriteLine("DummyReader.Dispose()");
}
}
class Test
{
static IEnumerable<int> FindValues(int valuesInReader)
{
Console.WriteLine("Take from the pool");
using (var reader = new DummyReader(valuesInReader))
{
while (reader.Read())
{
yield return reader.Count;
}
}
Console.WriteLine("Put back in the pool");
}
static void Main()
{
var data = FindValues(2).Take(2).ToArray();
Console.WriteLine(string.Join(",", data));
}
}
Jak je napsáno - modelování situace s tím, že čtenář najde pouze dvě hodnoty - výstup je:
Take from the pool
DummyReader.Dispose()
0,1
Všimněte si, že čtečka je zlikvidována, ale nikdy se nedostaneme tak daleko, abychom něco z bazénu vrátili. Pokud změníte Main
k modelování situace, kdy má čtenář pouze jednu hodnotu, takto:
var data = FindValues(1).Take(2).ToArray();
Poté projdeme celou cestu while
smyčka, takže se výstup změní:
Take from the pool
DummyReader.Dispose()
Put back in the pool
0
Doporučuji zkopírovat můj program a experimentovat s ním. Ujistěte se, že rozumíte všemu, co se děje... pak to můžete použít na svůj vlastní kód. Možná si budete chtít přečíst můj článek o podrobnostech implementace bloku iterátoru taky.