Я использую yield return
для перебора записей SqlDataReader
:
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();
}
}
}
Затем я использую адаптированную версию этого принятого ответа. для "сжатия" множества итераторов вместе:
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*/
}
В приведенном выше методе Dispose()
перечислителя не вызывается явно, и, поскольку они не используются в операторах using
или foreach
, останется ли базовый итератор в открытом состоянии? В моем случае с открытым SqlConnection
.
Должен ли я вызывать Dispose()
счетчиков, чтобы убедиться, что вся нижестоящая цепочка закрыта?
using
? Он вызывается автоматически, когда заканчивается контекст блока, который включаетyield
иreturn
. - person Yuck   schedule 24.01.2014using
. - person Oliver   schedule 24.01.2014