Pur comprendendo come funziona la parola chiave yield
, mi sono imbattuto in link1 e link2 su StackOverflow che promuove l'uso di yield return
durante l'iterazione su DataReader e soddisfa anche le mie esigenze. Ma mi chiedo cosa succede, se uso yield return
come mostrato di seguito e se non faccio scorrere l'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 finally di GetRecords()
non è stato eseguito. Come posso garantire la chiusura della connessione DB? C'è un modo migliore rispetto all'utilizzo della parola chiave yield
? Sto cercando di progettare una classe personalizzata che sarà responsabile dell'esecuzione di SQL selezionati e stored procedure su DB e restituirà il risultato. Ma non voglio restituire il DataReader al chiamante. Inoltre, voglio assicurarmi che la connessione venga chiusa in tutti gli scenari.
Modifica Modificata la risposta alla risposta di Ben in quanto non è corretto aspettarsi che i chiamanti del metodo utilizzino il metodo correttamente e rispetto alla connessione DB sarà più costoso se il metodo è chiamato più volte per no ragione.
Grazie Jakob e Ben per la spiegazione dettagliata.