Skip to content

Trampoline

1. 概要

Trampoline は、再入(reentrancy)を防止するためにキューを使って通知を直列化するオペレーターです。OnNext ハンドラ内から新たな通知が発行された場合、内側の通知はキューに入れられ、現在の通知の処理が完了してから順次配信されます。

2. シグネチャ

デフォルト

csharp
public static Observable<T> Trampoline<T>(
    this Observable<T> source)

再入が発生した場合に通知をキューに入れて直列化する Observable を返します。

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

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

通知の処理中に新しい通知が発行された場合、内側の通知はキューに入れられ、外側の処理が完了した後に配信されます。図では入力シーケンス側の矢印で、abc の処理中に再入通知 ABC が発生する関係を示しています。Trampoline 後は、それらがその場で割り込まず、後続の通知として a → b → c → A → B → C の順に配信されます。

4. サンプルコード

csharp
var subject = new Subject<int>();

// Trampoline で再入を防止
subject.Trampoline().Subscribe(x =>
{
    Console.WriteLine($"開始: {x}");
    if (x < 3)
    {
        // OnNext ハンドラ内から再帰的に通知を発行
        // Trampoline により、この通知は現在の処理完了後にキューから配信される
        subject.OnNext(x + 1);
    }
    Console.WriteLine($"終了: {x}");
});

subject.OnNext(1);
// 出力:
// 開始: 1
// 終了: 1
// 開始: 2
// 終了: 2
// 開始: 3
// 終了: 3

5. 補足

Synchronize との違いに注意してください。Trampoline はキューイングにより同一スレッド内での再入を安全に処理します。Synchronizelock によりマルチスレッドからの同時アクセスを排他制御します。

  • 再帰的な通知が発生する場合Trampoline を使用。Synchronizelock では再入によるデッドロックが発生する可能性があります。
  • 複数スレッドから通知される場合Synchronize を使用。