Comprendendo come yield
funziona la parola chiave, mi sono imbattuto in link1 e link2 su StackOverflow che sostiene l'uso di yield return
iterando su DataReader e soddisfa anche le mie esigenze. Ma mi chiedo cosa succede se uso yield return
come mostrato di seguito e se non eseguo iterazioni sull'intero DataReader, la connessione DB rimarrà aperta per sempre?
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;
}
}
Ho provato lo stesso esempio in un'app console di esempio e ho notato durante il debug che il blocco di infine GetRecords()
non viene eseguito. Come posso garantire quindi la chiusura di DB Connection? Esiste un modo migliore rispetto all'uso della yield
parola chiave? Sto cercando di progettare una classe personalizzata che sarà responsabile dell'esecuzione di determinati SQL e stored procedure su DB e restituirà il risultato. Ma non voglio restituire il DataReader al chiamante. Inoltre voglio assicurarmi che la connessione verrà chiusa in tutti gli scenari.
Modifica Modificata la risposta alla risposta di Ben poiché non è corretto aspettarsi che i chiamanti del metodo utilizzino correttamente il metodo e rispetto alla connessione DB sarà più costoso se il metodo viene chiamato più volte senza motivo.
Grazie Jakob e Ben per la spiegazione dettagliata.