I'm using yield return
to iterate over an SqlDataReader
's records:
IEnumerable<Reading> GetReadings() {
using (var connection = new SqlConnection(_connectionString))
{
using (var command = new SqlCommand(_query, connection))
{
connection.Open();
using (var reader = command.ExecuteReader())
{
while (reader.Read())
{
yield return new Reading
{
End = reader.GetDateTime(0),
Value = reader.GetDouble(1)
};
}
}
connection.Close();
}
}
}
I'm then using an adapted version of this accepted answer to "zip" many iterators together:
var enumerators = data.Select(d => new
{
d.Key,
Enumerator = d.Value.GetEnumerator()
}).ToList();
while (true)
{
foreach (var item in enumerators)
{
if (!item.Enumerator.MoveNext())
{
yield break;
}
/*snip*/
}
/*snip*/
}
In the method above, the enumerator's Dispose()
is not explicitly called, and because they are not used within a using
or foreach
statement, would the underlying iterator remain in an open state? In my case with an open SqlConnection
.
Should I be calling Dispose()
on the enumerators to make sure the whole downstream chain is closed?
using
syntax? It gets called automatically when the block context ends, which includesyield
andreturn
. – Ricardousing
. – Douma