Oli*_*ver 6 c# enumeration enumerator yield-return
我正在使用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();
}
}
}
Run Code Online (Sandbox Code Playgroud)
然后我使用这个被接受的答案的改编版本来"拉"许多迭代器:
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*/
}
Run Code Online (Sandbox Code Playgroud)
在上面的方法中,Dispose()没有显式调用枚举器,并且因为它们未在usingor foreach语句中使用,底层迭代器是否会保持打开状态?在我打开的情况下SqlConnection.
我是否应该呼吁Dispose()调查员确保整个下游链关闭?
Eri*_*ert 19
枚举这个迭代器时,如果枚举器
Dispose()未被显式调用,并且未在using语句中使用,那么底层迭代器是否会保持打开状态?
让我重新将这个问题改成一个更容易回答的形式.
当使用
foreach通过包含using语句的迭代器块进行枚举时,控件离开循环时是否会释放资源?
是.
什么机制确保这一点?
这三个:
一个using说法是只写一个方便的方法try-finally,其中finally资源的处置.
该foreach回路也为方便语法try-finally,并再次,在finally通话Dispose时控制叶枚举循环.
由迭代器块生成的枚举器实现IDisposable.调用Dispose()它可确保finally执行迭代器块中的所有块,包括finally来自using语句的块.
如果我避免
foreach循环,调用GetEnumerator自己,并且不调用Dispose枚举器,我是否保证finally枚举器的块将运行?
不. 始终处置您的普查员.他们实施IDisposable是有原因的.
那现在清楚了吗?
如果这个主题感兴趣,那么你应该阅读我关于C#中迭代器块的设计特征的长篇系列.
http://blogs.msdn.com/b/ericlippert/archive/tags/iterators/