C# 8 から導入された非同期ストリーム機能を使う
C# 8 以前では以下のような形で async/await
を用いたコード上で yield return
をすることはできなかった。
public async Task<IEnumerable<int>> GetHogesAsync() { var items = await GetItemsAsync(); foreach (var item in items) { yield return item + 10; // <- ここでコンパイルエラー } }
これが、C# 8 で上記とは異なる形で、Task<IEnumerable<T>>
の代わりに IAsyncEnumerable<T>
を使うことで実現可能となった。
IAsyncEnumerable<T>
は foreach を await することで非同期的に列挙することができる。
具体的には以下の構文となる。
await foreach (var item in items) { }
現時点ではLINQ的な拡張が用意されていないため、もし LINQ のようなことがしたい場合は自前で用意する必要がある。*1
実際にはこんな感じなコードを書けばとりあえずLINQっぽく書くことができるようになる。
が、これだけだと例えば Task<IEnumerable<T>>
な型だったり Task<T[]>
な型だったりに対応できないので AsAsyncEnumerable<T>
な拡張を用意してあげても良いかもしれない。
この場合、Task<IEnumerable<T>>
だけだと C# の型推論の関係上 Task<T[]>
などを網羅できないので、個別に記述していく必要がある。
*1:NuGet が何かあるかもしれないけど未調査