Ao entender como a yield
palavra-chave funciona, deparei-me com o link1 e o link2 no StackOverflow, que defendem o uso de yield return
iterações no DataReader e também atendem às minhas necessidades. Mas isso me faz pensar no que acontece, se eu usar yield return
como mostrado abaixo e se eu não percorrer todo o DataReader, a conexão com o banco de dados permanecerá aberta para 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;
}
}
Tentei o mesmo exemplo em um exemplo de aplicativo de console e notei, durante a depuração, que o bloco finalmente GetRecords()
não é executado. Como posso garantir o fechamento do DB Connection? Existe uma maneira melhor do que usar yield
palavras-chave? Estou tentando criar uma classe personalizada que será responsável pela execução de SQLs selecionados e procedimentos armazenados no DB e retornará o resultado. Mas não quero devolver o DataReader ao chamador. Também quero ter certeza de que a conexão será fechada em todos os cenários.
Editar A resposta foi alterada para a resposta de Ben, pois é incorreto esperar que os chamadores do método usem o método corretamente e, com relação à conexão com o banco de dados, será mais caro se o método for chamado várias vezes sem motivo.
Obrigado Jakob e Ben pela explicação detalhada.