Skip to content

Race

1. 概要

Race は、複数の Observable ソースを同時に購読し、最初に値を発行したソースのみを採用するファクトリメソッドです。勝者が決まると、他のすべてのソースは即座に購読解除されます。

フォールバック戦略やタイムアウト競争など、複数の候補から最も応答が速いものを選びたい場合に使用します。

2. シグネチャ

params 配列

csharp
public static Observable<T> Race<T>(params Observable<T>[] sources)

可変長引数で複数のソースを指定します。

csharp
Observable.Race(primarySource, fallbackSource)

IEnumerable

csharp
public static Observable<T> Race<T>(IEnumerable<Observable<T>> sources)

ソースのコレクションを動的に渡す場合に使用します。

csharp
var sources = new List<Observable<string>> { source1, source2, source3 };
Observable.Race(sources)

オーバーロードの使い分け

オーバーロード使う場面
Race<T>(params Observable<T>[])ソース数がコンパイル時に決まっている場合
Race<T>(IEnumerable<Observable<T>>)ソースを動的に生成・収集する場合

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

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

Race はすべてのソースを同時に購読し、最初に値を発行したソースが勝者となります。勝者のソースからの後続の値はすべて転送され、他のソースは即座に購読解除されます。勝者のソースが完了またはエラーになると、結果も同様に完了またはエラーとなります。

4. サンプルコード

csharp
using R3;

// 応答が速いソースを採用する
var slow = new Subject<string>();
var fast = new Subject<string>();

Observable.Race(slow, fast)
    .Subscribe(
        x => Console.WriteLine($"値: {x}"),
        r => Console.WriteLine($"完了: {r}"));

fast.OnNext("速い!");     // 出力: 値: 速い!(fast が勝者に決定、slow は購読解除)
slow.OnNext("遅い…");     // 出力なし(slow は既に購読解除済み)
fast.OnNext("2番目");      // 出力: 値: 2番目
fast.OnCompleted();        // 出力: 完了: Success

5. 補足

オペレーター版との違い

オペレーター版 Race は、拡張メソッドとして source.Race(second) の形式で使用できます。2 つの Observable を競争させる場合はオペレーター版、3 つ以上または動的なソース集合から最初に値を発行したものを採用する場合は、この静的ファクトリメソッド版が向いています。