🔄

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

2024/11/13に公開
2

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

いい方法がないかなと思っていたら System.Linq.AsyncToListAsync<T> メソッドがありました。みんな大好き Reactive Extensions に含まれるパッケージですね。

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

ToListAsync<T> メソッドはそのままでは後続のメソッド チェーンができないので、AsTask メソッドや ContinueWith メソッドを使ってつなげることになります。具体的には以下のようなコードになります。

var blobContainerClient = new BlobContainerClient("{{connectionstring}}", "{{containername}}");
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 を使っているのを忘れていました。ご指摘ありがとうございます!