sskiles devblog

tochunkedlistasync()

I recently came across this fun little snippet I wrote a while back. I don’t remember the exact case where I used it, but I thought it was worth sharing. I think I needed to process a huge IEnumerable<T> and wanted to distribute it as simply as possible. This is a simple extension method on IEnumerable<T> that returns it as multiple List<T> objects from a IAsyncEnumerable<List<T>>. The chunk size is configurable, and the method is cancellable.

I present to you the ToChunkedListAsync extension method:

public static async IAsyncEnumerable<List<T>> ToChunkedListAsync<T>(
    this IEnumerable<T> enumerable,
    int chunkSize = 100,
    [EnumeratorCancellation] CancellationToken token = default)
{
    var itemList = new List<T>(chunkSize);
    var enumerator = enumerable.GetEnumerator();
    for (var count = 1; enumerator.MoveNext(); count++)
    {
        token.ThrowIfCancellationRequested();
        var item = enumerator.Current;
        itemList.Add(item);
        if (count % chunkSize == 0)
        {
            yield return itemList;
            itemList.Clear();
            await Task.Yield();
        }
    }

    if (itemList.Count > 0)
    {
        yield return itemList;
    }
}

I think my original idea for the IEnumerable<T> distribution would have spent more time on the distribution than the actual processing. This seemed to be a quick and easy way to break it into chunks get the job done. It’s also lowers the memory pressure as opposed to a single huge ToList. Here’s a simple example of how to use it:

await foreach (var chunk in Enumerable.Range(1, 42).ToChunkedListAsync(10))
{
    Console.WriteLine($"Chunk: {string.Join(", ", chunk)}");
}
// Output:
// Chunk: 1, 2, 3, 4, 5, 6, 7, 8, 9, 10
// Chunk: 11, 12, 13, 14, 15, 16, 17, 18, 19, 20
// Chunk: 21, 22, 23, 24, 25, 26, 27, 28, 29, 30
// Chunk: 31, 32, 33, 34, 35, 36, 37, 38, 39, 40
// Chunk: 41, 42

You may never need this, but I thought it was a fun little snippet to share. It may give you some ideas for something else.

© 2026 Shane Skiles