Amphisbaena is a mythological serpent with a head at each end.
For a long time have we good old LINQ to Objects which is lazy and synchronous. This .Net 5 library is a LINQ to ChannelReader from System.Threading.Channels; and this implementation is eager and asynchronous.
Despite different execution model, I've tried to preserve the syntax as much as I can:
// 1 + 2 + 3 + ... + 100
var sum = await Enumerable
.Range(1, 100)
.ToChannelReader()
.Aggregate((s, a) => s + a);
However, async
brings some specific:
var strangeSum = await Enumerable
.Range(1, 1000)
.ToChannelReader()
.ToBatch((batch, item, index) => batch.Count < 100,
new ChannelParallelOptions() { DegreeOfParallelism = 2 })
.ActForEach(batch => logger.Debug($"{batch.Length}"),
batch => batch.Length < 100)
.ForEach(batch => batch.Sum(),
new ChannelParallelOptions() { DegreeOfParallelism = 4 })
.DetachAttach(item => item > 20_000,
process => process.Select(item => item * 2))
.Aggregate((s, a) => s + a);