Tôi nghi ngờ đây là sự cố, ở cuối phương pháp:
this.connectionPool.Putback(sqlConnection);
Bạn chỉ đang lấy hai phần tử từ trình lặp - vì vậy bạn không bao giờ hoàn thành while
vòng lặp trừ khi thực sự chỉ có một giá trị được trả về từ trình đọc. Bây giờ bạn đang sử dụng LINQ, LINQ sẽ tự động gọi Dispose()
trên trình lặp, vì vậy using
tuyên bố sẽ vẫn loại bỏ trình đọc - nhưng bạn không đặt kết nối trở lại nhóm. Nếu bạn làm điều đó trong finally
chặn, tôi nghĩ bạn sẽ ổn:
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);
}
Hoặc lý tưởng hơn, nếu nhóm kết nối của bạn là do bạn tự triển khai, hãy tạo Take
trả về một cái gì đó triển khai IDisposable
và trả kết nối trở lại nhóm khi hoàn tất.
Đây là một chương trình ngắn nhưng đầy đủ để chứng minh những gì đang diễn ra mà không có bất kỳ cơ sở dữ liệu thực tế nào liên quan:
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));
}
}
Như đã viết - mô hình hóa tình huống với người đọc chỉ tìm thấy hai giá trị - kết quả đầu ra là:
Take from the pool
DummyReader.Dispose()
0,1
Lưu ý rằng đầu đọc được xử lý, nhưng chúng tôi không bao giờ trả lại được bất cứ thứ gì từ hồ bơi. Nếu bạn thay đổi Main
để mô hình hóa tình huống trong đó người đọc chỉ có một giá trị, như sau:
var data = FindValues(1).Take(2).ToArray();
Sau đó, chúng tôi nhận được tất cả các cách thông qua while
vòng lặp, vì vậy đầu ra thay đổi:
Take from the pool
DummyReader.Dispose()
Put back in the pool
0
Tôi đề nghị bạn sao chép chương trình của tôi và thử nghiệm với nó. Đảm bảo rằng bạn hiểu mọi thứ về những gì đang diễn ra ... sau đó bạn có thể áp dụng nó cho mã của riêng mình. Bạn có thể muốn đọc bài viết của tôi về chi tiết triển khai khối trình lặp quá.