Saya menduga ini masalahnya, di akhir metode:
this.connectionPool.Putback(sqlConnection);
Anda hanya mengambil dua elemen dari iterator - jadi Anda tidak pernah menyelesaikan while
loop kecuali sebenarnya hanya ada satu nilai yang dikembalikan dari pembaca. Sekarang Anda menggunakan LINQ, yang secara otomatis akan memanggil Dispose()
pada iterator, jadi using
pernyataan akan tetap membuang pembaca - tetapi Anda tidak mengembalikan koneksi ke kumpulan. Jika Anda melakukannya dalam finally
blokir, saya pikir Anda akan baik-baik saja:
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);
}
Atau idealnya, jika kumpulan koneksi Anda adalah implementasi Anda sendiri, buat Take
kembalikan sesuatu yang mengimplementasikan IDisposable
dan mengembalikan koneksi kembali ke kumpulan setelah selesai.
Berikut adalah program singkat namun lengkap untuk mendemonstrasikan apa yang terjadi, tanpa melibatkan basis data aktual:
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));
}
}
Seperti yang tertulis - memodelkan situasi dengan pembaca hanya menemukan dua nilai - outputnya adalah:
Take from the pool
DummyReader.Dispose()
0,1
Perhatikan bahwa pembaca dibuang, tetapi kami tidak pernah sampai sejauh mengembalikan apa pun dari kumpulan. Jika Anda mengubah Main
untuk memodelkan situasi di mana pembaca hanya memiliki satu nilai, seperti ini:
var data = FindValues(1).Take(2).ToArray();
Kemudian kita mendapatkan semua jalan melalui while
loop, sehingga output berubah:
Take from the pool
DummyReader.Dispose()
Put back in the pool
0
Saya sarankan Anda menyalin program saya dan bereksperimen dengannya. Pastikan Anda memahami segala sesuatu tentang apa yang terjadi... kemudian Anda dapat menerapkannya ke kode Anda sendiri. Anda mungkin ingin membaca artikel saya di detail penerapan blok iterator juga.