Tout en comprenant la façon dont les yield
œuvres de mots clés, je suis tombé sur link1 et lien2 sur StackOverflow qui préconise l'utilisation de yield return
tout itérer sur le DataReader et il convient à mes besoins aussi bien. Mais cela me fait me demander ce qui se passe, si j'utilise yield return
comme indiqué ci-dessous et si je n'itère pas à travers DataReader entier, la connexion DB restera-t-elle ouverte pour toujours?
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;
}
}
J'ai essayé le même exemple dans un exemple d'application console et j'ai remarqué lors du débogage que le bloc finalement de GetRecords()
n'était pas exécuté. Comment puis-je assurer la fermeture de DB Connection? Existe-t-il un meilleur moyen que d'utiliser un yield
mot-clé? J'essaie de concevoir une classe personnalisée qui sera responsable de l'exécution de certains SQL et procédures stockées sur DB et retournera le résultat. Mais je ne veux pas retourner le DataReader à l'appelant. Je veux également m'assurer que la connexion sera fermée dans tous les scénarios.
Modifier la réponse à la réponse de Ben car il est incorrect de s'attendre à ce que les appelants utilisent correctement la méthode et en ce qui concerne la connexion DB, cela coûtera plus cher si la méthode est appelée plusieurs fois sans raison.
Merci Jakob et Ben pour l'explication détaillée.