Skip to content

CreateFrom

1. 概要

CreateFrom は、IAsyncEnumerable<T> を返すファクトリ関数から Observable を生成するファクトリメソッドです。非同期イテレータ(yield return)で発行される各値が Observable の要素として通知されます。

Create と比べて、値を順番に発行するシナリオではより簡潔に記述できます。

2. シグネチャ

基本

csharp
public static Observable<T> CreateFrom<T>(Func<CancellationToken, IAsyncEnumerable<T>> factory)

購読時にファクトリ関数が呼び出され、IAsyncEnumerable<T> の各要素が順に発行されます。列挙が完了するとシーケンスが完了します。CancellationToken は購読解除時にキャンセルされます。

csharp
Observable.CreateFrom<int>(async ct => AsyncEnumerate(ct))

ステート付き

csharp
public static Observable<T> CreateFrom<T, TState>(TState state, Func<CancellationToken, TState, IAsyncEnumerable<T>> factory)

state を渡すことでクロージャのキャプチャを回避し、アロケーションを削減できます。

csharp
Observable.CreateFrom<int, int>(maxCount, async (ct, max) => GenerateAsync(ct, max))

3. マーブルダイアグラム

CreateFrom のマーブルダイアグラム

購読時に IAsyncEnumerable の列挙が開始され、yield return されるたびに値が発行されます。列挙が完了するとシーケンスが完了します。

4. サンプルコード

csharp
using R3;

// === 基本: 非同期イテレータで値を生成 ===
Observable.CreateFrom<int>(async ct =>
    {
        return GenerateNumbersAsync(ct);
    })
    .Subscribe(
        x => Console.WriteLine($"値: {x}"),
        _ => Console.WriteLine("完了"));

async IAsyncEnumerable<int> GenerateNumbersAsync(
    [System.Runtime.CompilerServices.EnumeratorCancellation] CancellationToken ct = default)
{
    for (int i = 1; i <= 5; i++)
    {
        await Task.Delay(200, ct);
        yield return i;
    }
}
// 出力(200ms ごと): 値: 1
// 出力: 値: 2
// 出力: 値: 3
// 出力: 値: 4
// 出力: 値: 5
// 出力: 完了

// === ステート付き: 外部パラメータを渡す ===
Observable.CreateFrom<string, string>("https://api.example.com", async (ct, baseUrl) =>
    {
        return FetchPagesAsync(baseUrl, ct);
    })
    .Subscribe(page => Console.WriteLine($"ページ取得: {page}"));

async IAsyncEnumerable<string> FetchPagesAsync(
    string baseUrl,
    [System.Runtime.CompilerServices.EnumeratorCancellation] CancellationToken ct = default)
{
    for (int page = 1; page <= 3; page++)
    {
        await Task.Delay(100, ct);
        yield return $"{baseUrl}/page/{page}";
    }
}
// 出力: ページ取得: https://api.example.com/page/1
// 出力: ページ取得: https://api.example.com/page/2
// 出力: ページ取得: https://api.example.com/page/3

5. 補足

Create との違い

CreateObserver<T> を直接操作するため、複数の値を任意のタイミングで発行したり、エラーを通知したりといった細かい制御が可能です。一方、CreateFromIAsyncEnumerableyield return パターンを使うため、値を順番に発行する場面ではより自然でシンプルな記述ができます。