導入
「DBやAPIから結果が1件ずつ、非同期に届く」——そんなストリーム状のデータを自然に扱えるのがIAsyncEnumerable<T>とawait foreachです。yield(イテレータ)の非同期版で、全件そろうのを待たずに届いた分から処理できます。
図解
flowchart LR
S["データ源(DB/API)"] -->|1件ずつ非同期に| Y["async + yield return"]
Y --> AF["await foreach で受け取る"]
AF --> P["届いた分から順に処理"]
サンプル
// await foreach: 非同期に1件ずつ届く列を受け取る
await foreach (int n in GenerateAsync())
Console.Write($"{n} "); // 1 2 3
Console.WriteLine();
// async + yield return で「非同期の列」を作る(yieldの非同期版)
async IAsyncEnumerable<int> GenerateAsync()
{
for (int i = 1; i <= 3; i++)
{
await Task.Delay(10); // 実際はDB/APIから1件取得するイメージ
yield return i;
}
}
IAsyncEnumerable<T>は「非同期に1件ずつ取り出せる列」- 受け取る側は
await foreach、作る側はasyncメソッド+yield return - 全件そろうのを待たず、届いた分から処理できる(大量データ・ストリーミングに有効)
演習
async IAsyncEnumerable<int> CountAsync()
{
yield return 1;
await Task.Delay(1);
yield return 2;
}
// TODO: await foreach で CountAsync() の各値を "1 2 " のように空白区切りで出力してください
___
- 期待される出力:
1 2
ヒント1を見る
await foreach (int n in CountAsync()) Console.Write($"{n} ");
ヒント2を見る
通常のforeachの前にawaitを付けるだけです
まとめ
IAsyncEnumerable<T>+await foreachで非同期に届く列を扱える- 作る側は
asyncメソッド+yield return(yieldの非同期版) - 全件待たずに処理できるのでストリーミングや大量データに向く
次章: 外部のサーバーと通信する「HTTP通信」へ進みます。