ในขณะที่ทำความเข้าใจวิธีการyield
ทำงานของคำหลักฉันเจอlink1และlink2บน StackOverflow ซึ่งสนับสนุนการใช้งานyield return
ในขณะวนซ้ำ DataReader และเหมาะสมกับความต้องการของฉันเช่นกัน แต่มันทำให้ฉันสงสัยว่าเกิดอะไรขึ้นถ้าฉันใช้yield return
ดังที่แสดงด้านล่างและถ้าฉันไม่ทำซ้ำใน DataReader ทั้งหมดการเชื่อมต่อฐานข้อมูลจะเปิดตลอดไปหรือไม่
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;
}
}
ฉันลองตัวอย่างเดียวกันในตัวอย่างแอปคอนโซลและสังเกตว่าในขณะที่การดีบั๊กที่บล็อกในที่สุด GetRecords()
จะไม่ถูกดำเนินการ ฉันจะมั่นใจได้อย่างไรว่าการปิดการเชื่อมต่อฐานข้อมูล มีวิธีที่ดีกว่าการใช้yield
คำหลักหรือไม่ ฉันพยายามออกแบบคลาสที่กำหนดเองซึ่งจะรับผิดชอบการดำเนินการเลือก SQL และโพรซีเดอร์ที่เก็บไว้บน DB และจะส่งคืนผลลัพธ์ แต่ฉันไม่ต้องการคืน DataReader กลับไปยังผู้โทร นอกจากนี้ฉันต้องการตรวจสอบให้แน่ใจว่าการเชื่อมต่อจะถูกปิดในทุกสถานการณ์
แก้ไขเปลี่ยนคำตอบสำหรับคำตอบของเบ็นเนื่องจากไม่ถูกต้องที่ผู้โทรเมธอดจะใช้วิธีการอย่างถูกต้องและสำหรับการเชื่อมต่อฐานข้อมูลนั้นจะมีราคาแพงกว่าถ้าวิธีนั้นถูกเรียกหลายครั้งโดยไม่มีเหตุผล
ขอบคุณ Jakob และ Ben สำหรับคำอธิบายโดยละเอียด