Sospecho que este es el problema, al final del método:
this.connectionPool.Putback(sqlConnection);
Solo estás tomando dos elementos del iterador, por lo que nunca completa el while
bucle a menos que en realidad solo haya un valor devuelto por el lector. Ahora está usando LINQ, que llamará automáticamente a Dispose()
en el iterador, entonces using
la declaración aún se deshará del lector, pero no volverá a colocar la conexión en el grupo. Si haces eso en un finally
block, creo que estarás bien:
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);
}
O idealmente, si su grupo de conexiones es su propia implementación, haga Take
devuelve algo que implementa IDisposable
y devuelve la conexión al grupo cuando termina.
Aquí hay un programa corto pero completo para demostrar lo que está pasando, sin ninguna base de datos real involucrada:
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));
}
}
Tal como está escrito, modelando la situación con el lector solo encontrando dos valores, el resultado es:
Take from the pool
DummyReader.Dispose()
0,1
Tenga en cuenta que el lector se desecha, pero nunca llegamos a devolver nada de la piscina. Si cambia Main
para modelar la situación en la que el lector solo tiene un valor, así:
var data = FindValues(1).Take(2).ToArray();
Luego recorremos todo el while
bucle, por lo que la salida cambia:
Take from the pool
DummyReader.Dispose()
Put back in the pool
0
Le sugiero que copie mi programa y experimente con él. Asegúrese de entender todo acerca de lo que está pasando... luego podrá aplicarlo a su propio código. Es posible que desee leer mi artículo sobre detalles de implementación del bloque iterador también.