Trong khi hiểu cách yield
hoạt động của từ khóa, tôi đã xem qua link1 và link2 trên StackOverflow, chủ trương sử dụng yield return
trong khi lặp qua DataReader và nó cũng phù hợp với nhu cầu của tôi. Nhưng nó làm tôi tự hỏi điều gì sẽ xảy ra, nếu tôi sử dụng yield return
như được hiển thị bên dưới và nếu tôi không lặp qua toàn bộ DataReader, liệu kết nối DB có mở mãi mãi không?
IEnumerable<IDataRecord> GetRecords()
{
SqlConnection myConnection = new SqlConnection(@"...");
SqlCommand myCommand = new SqlCommand(@"...", myConnection);
myCommand.CommandType = System.Data.CommandType.Text;
myConnection.Open();
myReader = myCommand.ExecuteReader(CommandBehavior.CloseConnection);
try
{
while (myReader.Read())
{
yield return myReader;
}
}
finally
{
myReader.Close();
}
}
void AnotherMethod()
{
foreach(var rec in GetRecords())
{
i++;
System.Console.WriteLine(rec.GetString(1));
if (i == 5)
break;
}
}
Tôi đã thử ví dụ tương tự trong Ứng dụng Console mẫu và nhận thấy trong khi gỡ lỗi rằng khối cuối cùng GetRecords()
không được thực thi. Làm thế nào tôi có thể đảm bảo sau đó đóng kết nối DB? Có cách nào tốt hơn là sử dụng yield
từ khóa không? Tôi đang cố gắng thiết kế một lớp tùy chỉnh sẽ chịu trách nhiệm thực thi các SQL được chọn và các thủ tục được lưu trữ trên DB và sẽ trả về kết quả. Nhưng tôi không muốn trả lại DataReader cho người gọi. Ngoài ra tôi muốn đảm bảo rằng kết nối sẽ được đóng lại trong tất cả các tình huống.
Biên tập Thay đổi câu trả lời cho câu trả lời của Ben vì không chính xác khi mong đợi người gọi phương thức sử dụng phương thức này một cách chính xác và đối với kết nối DB sẽ tốn kém hơn nếu phương thức được gọi nhiều lần mà không có lý do.
Cảm ơn Jakob và Ben đã giải thích chi tiết.