IEnumerable.Take()上的延迟加载

Dav*_*New 3 .net c# linq lazy-loading

有人可以向我解释为什么我的IEnumerable在GetMessages()上没有延迟加载.拿(5)?如果我调试foreach循环,它似乎延迟加载一个消息一次为前5个,将它们添加到listBox1,但然后在这5个之后它将继续填充列表的其余部分(这需要一分钟)在循环之后继续执行之前.

    public void PopulateMessages()
    {
        foreach (string message in GetMessages().Take(5))
        {
            listBox1.Items.Add(message);
        }
    }

    private static IEnumerable<string> GetMessages()
    {
        using (var conn = new SqlConnection(connectionString))
        {
            conn.Open();

            // The Message table has thousands of rows
            SqlDataReader reader = new SqlCommand("SELECT * FROM Message", conn).ExecuteReader();

            while (reader.Read())
            {
                yield return reader.GetString(0);
            }
        }
    }
Run Code Online (Sandbox Code Playgroud)

谢谢.

Mar*_*ell 5

然而,它延迟加载它们:sql命令仍在运行.你可能会尝试的一件事是using:

using(var cmd = new SqlCommand("SELECT * FROM Message", conn))
using(var reader = cmd.ExecuteReader())
{
    while (reader.Read())
    {
        yield return reader.GetString(0);
    }
}
Run Code Online (Sandbox Code Playgroud)

但是,最佳解决方案是生成带有a的TSQL TOP 5,或者TOP (@count)如果要进行参数化则生成TSQL .

然后,这将尽快处理读者和命令.这样说:连接已经正确处理.

  • @davenewza从SQL服务器返回的TDS流就是:一个流.它不是一个游标,你告诉服务器"下一行,下一行,下一行".它正忙着把所有**行放在网络插座上,而你的命令最好的就是大声喊叫"哇嘿!我正在关机!你现在可以停下来!coooo-eeeee!嘿,服务器!你在听我说吗?".对于基本命令,在大多数情况下,在任何取消到达服务器之前,整个数据已经在网络缓冲区**中**. (2认同)