Lazy loading on IEnumerable.Take()

.net, c#, lazy-loading, linq

Solution

It is lazy loading them, however: the sql command is still running. One thing you might try is a bit more `using`:

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

However, the optimal solution would be to generate the TSQL with a `TOP 5` in it, or maybe a `TOP (@count)` if you want to parameterise.

This will then dispose the reader and command as soon as possible. Saying that: the connection is already correctly disposed.

Problem

Could someone explain to me why my IEnumerable is not lazy loaded on GetMessages().Take(5)? If I debug the foreach loop, it appears to lazy load one message at a time for the first 5, adding them to the listBox1, but then after those 5 it will continue to populate the rest of the list (which takes like a minute) before continuing executing after the loop. ``` 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); } } } ``` Thanks.

Original source