使用yield遍历数据读取器可能不会关闭连接吗? [英] Using yield to iterate over a datareader might not close the connection?

查看:72
本文介绍了使用yield遍历数据读取器可能不会关闭连接吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

  public IEnumerable< object> ExecuteSelect(字符串commandText)
{
使用(IDbConnection连接= CreateConnection())
{
使用(IDbCommand cmd = CreateCommand(commandText,连接))
{
connection.Open();
使用(IDbDataReader reader = cmd.ExecuteReader())
{
while(reader.Read())
{
收益回报阅读器[ SomeField];
}
}
connection.Close();
}
}
}

我是这样认为的在此示例代码中,如果我们不遍历整个数据读取器,则不会关闭连接?



这里是一个示例,如果我正确理解了yield的话,它不会关闭连接。

  foreach(ExecuteSelect(commandText)中的对象obj)
{
break;
}

对于可能不是灾难性的数据库连接,我想GC可以清理最终,但是如果不是连接,它是更关键的资源怎么办?

解决方案

编译器综合实现的Iterator IDisposable ,当 foreach 循环退出时, foreach 调用



迭代器的 Dispose()方法将使用



只要您在 foreach 循环中使用迭代器, using()块,或以其他方式调用 Dispose()方法,将进行Iterator的清理。 / p>

Here is a sample code to retrieve data from a database using the yield keyword that I found in a few place while googling around :

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();
        }
    }
}

Am I correct in thinking that in this sample code, the connection would not be closed if we do not iterate over the whole datareader ?

Here is an example that would not close the connection, if I understand yield correctly..

foreach(object obj in ExecuteSelect(commandText))
{
  break;
}

For a db connection that might not be catastrophic, I suppose the GC would clean it up eventually, but what if instead of a connection it was a more critical resource?

解决方案

The Iterator that the compiler synthesises implements IDisposable, which foreach calls when the foreach loop is exited.

The Iterator's Dispose() method will clean up the using statements on early exit.

As long as you use the iterator in a foreach loop, using() block, or call the Dispose() method in some other way, the cleanup of the Iterator will happen.

这篇关于使用yield遍历数据读取器可能不会关闭连接吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆