使用yield迭代datareader可能无法关闭连接?

Joe*_*eau 15 yield .net-2.0

下面是一个示例代码,用于使用我在google搜索时在几个地方找到的yield关键字从数据库中检索数据:

public IEnumerable<object> ExecuteSelect(string commandText)
{
    using (IDbConnection connection = CreateConnection())
    {
        using (IDbCommand cmd = CreateCommand(commandText, connection))
        {
             connection.Open();
             using (IDbDataReader reader = cmd.ExecuteReader())
             {
                while(reader.Read())
                {
                    yield return reader["SomeField"];
                }
             }
             connection.Close();
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

我是否认为在此示例代码中,如果我们不遍历整个datareader,连接将不会被关闭?

如果我理解正确的收益,这是一个不会关闭连接的例子.

foreach(object obj in ExecuteSelect(commandText))
{
  break;
}
Run Code Online (Sandbox Code Playgroud)

对于可能不是灾难性的数据库连接,我想GC最终会将其清理干净,但是如果不是连接它会是一个更关键的资源呢?

Dou*_*der 12

编译器合成的迭代器实现了IDisposable,当foreach循环退出时,它会调用.

Iterator的Dispose()方法将在早期退出时清除using语句.

只要在foreach循环中使用迭代器,使用()块或以其他方式调用Dispose()方法,就会发生迭代器的清理.