🔄

C# で IAsyncEnumerable<T> を List<T> に変換する

に公開
2

Azure SDK には結果を AsyncPageable<T> クラスで返すものが多くあります。さらにそこから AsyncPageable<T>.AsPages メソッドを呼び出すと IAsyncEnumerable<T> インターフェースの結果が得られます。IAsyncEnumerable<T> インターフェースは非同期ストリームと呼ばれ、効率的にデータを読み取ることができますが、残念ながら List<T> に変換するためのメソッドはありません。

良い方法がないかと考えていたところ、System.Linq.Async に ToListAsync<T> メソッドがあることを見つけました。これは Reactive Extensions に含まれるパッケージです。

https://www.nuget.org/packages/System.Linq.Async

ToListAsync<T> メソッドは、そのままでは後続のメソッドチェーンができません。そのため、AsTask メソッドや ContinueWith メソッドを使ってつなげる必要があります。具体的なコード例は次のとおりです。

var blobContainerClient = new BlobContainerClient("{{connection-string}}", "{{containe-rname}}");
var blobNames = await blobContainerClient
    .GetBlobsAsync()
    .ToListAsync()
    .AsTask()
    .ContinueWith(task => task.Result.Select(_ => _.Name));

Microsoft のドキュメントにも記載があります。

https://learn.microsoft.com/ja-jp/dotnet/azure/sdk/pagination?WT.mc_id=M365-MVP-5002941

Discussion

Mayuki SawatariMayuki Sawatari

ContinueWith メソッドを使わず

await blobContainerClient.GetBlobsAsync().Select(x => x.Name).ToListAsync();

または

var blobNames = (await blobContainerClient.GetBlobsAsync().ToListAsync())
    .Select(x => x.Name)
    .ToList();

ではどうでしょうか?

karamem0karamem0

コメントありがとうございます。
そうですね、await を () で囲むのが個人的に好きでなかったのでいつも ContinueWith を使っているのを忘れていました。ご指摘ありがとうございます!