C# 在IEnumerable.Take()上延迟加载

C# 在IEnumerable.Take()上延迟加载,c#,.net,linq,lazy-loading,C#,.net,Linq,Lazy Loading,有人能解释一下为什么我的IEnumerable不是懒加载到GetMessages()上的吗?如果我调试foreach循环,它似乎会在前5次延迟加载一条消息,将它们添加到listBox1,但在这5次之后,它将继续填充列表的其余部分(这需要一分钟),然后在循环之后继续执行 public void PopulateMessages() { foreach (string message in GetMessages().Take(5)) {

有人能解释一下为什么我的IEnumerable不是懒加载到GetMessages()上的吗?如果我调试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);
            }
        }
    }
public void PopulateMessages()
{
foreach(GetMessages()中的字符串消息。Take(5))
{
listBox1.Items.Add(消息);
}
}
私有静态IEnumerable GetMessages()
{
使用(var conn=newsqlconnection(connectionString))
{
conn.Open();
//消息表有数千行
SqlDataReader=newSqlCommand(“从消息中选择*”,conn).ExecuteReader();
while(reader.Read())
{
生成返回读取器.GetString(0);
}
}
}
谢谢。

加载它们很慢,但是:sql命令仍在运行。您可以尝试的一件事是更多地使用

using(var cmd = new SqlCommand("SELECT * FROM Message", conn))
using(var reader = cmd.ExecuteReader())
{
    while (reader.Read())
    {
        yield return reader.GetString(0);
    }
}
但是,最佳的解决方案是生成TSQL,其中包含
TOP 5
,或者如果要参数化,可以使用
TOP(@count)


这将尽快处理读取器和命令。说明:连接已正确处理。

您的意思是列表中的项目超过5项吗?正确,我希望在不将整个表加载到内存的情况下获得5项。但这不是一个现实世界的问题。我只是想了解延迟执行。如果你的列表框中有超过5个项目,那么事情就很糟糕了。对不起,听起来很难理解:但是你能确认你在列表框中添加了超过5项吗?对不起,我误解了你的问题!是的,列表框中只有5项:)谢谢。我认为通过使用SqlReader.Read(),我不需要返回整个结果。@davenewza从SQL server返回的TDS流就是:一个流。它不是告诉服务器“下一行,下一行,下一行”的光标。它正忙着在网络套接字上抛出所有的行,你的命令所能做的就是大声喊“哇嘿!我要关机了!你现在可以停下来了!嘿,服务器!你在听我说话吗?”。对于一个基本命令,在大多数情况下,在任何取消操作到达服务器之前,所有数据都已经在网络缓冲区中了。哈哈,我喜欢你的解释。谢谢-现在有道理了。