Project · Async
Bounded batch loader
Compose cancellable asynchronous work in small deterministic batches.
All C# source files below are loaded together in the playground. Files written by a run live in its virtual directory.
Program.cs
using System;
using System.Linq;
using System.Collections.Generic;
using System.Globalization;
using System.Text;
using System.Text.Json;
using System.Threading;
using System.Threading.Tasks;
using var cancellation = new CancellationTokenSource();
var values = await BatchLoader.LoadAsync(new[] { 1, 2, 3, 4, 5 }, 2, cancellation.Token);
Console.WriteLine(string.Join(",", values));
Async/BatchLoader.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
public static class BatchLoader
{
public static async Task<int[]> LoadAsync(IEnumerable<int> ids, int batchSize, CancellationToken token)
{
if (batchSize is < 1 or > 32) throw new ArgumentOutOfRangeException(nameof(batchSize));
var results = new List<int>();
foreach (var batch in ids.Chunk(batchSize))
{
token.ThrowIfCancellationRequested();
results.AddRange(await Task.WhenAll(batch.Select(id => LoadOneAsync(id, token))));
}
return results.ToArray();
}
private static async Task<int> LoadOneAsync(int id, CancellationToken token)
{
await Task.Delay(1, token);
return id * 10;
}
}
Boundedbatchloader.csproj
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net9.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>
</Project>