Trampoline
1. 概要
Trampoline は、再入(reentrancy)を防止するためにキューを使って通知を直列化するオペレーターです。OnNext ハンドラ内から新たな通知が発行された場合、内側の通知はキューに入れられ、現在の通知の処理が完了してから順次配信されます。
2. シグネチャ
デフォルト
csharp
public static Observable<T> Trampoline<T>(
this Observable<T> source)再入が発生した場合に通知をキューに入れて直列化する Observable を返します。
3. マーブルダイアグラム
通知の処理中に新しい通知が発行された場合、内側の通知はキューに入れられ、外側の処理が完了した後に配信されます。図では入力シーケンス側の矢印で、a、b、c の処理中に再入通知 A、B、C が発生する関係を示しています。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
// 終了: 35. 補足
Synchronize との違いに注意してください。Trampoline はキューイングにより同一スレッド内での再入を安全に処理します。Synchronize は lock によりマルチスレッドからの同時アクセスを排他制御します。
- 再帰的な通知が発生する場合 →
Trampolineを使用。Synchronizeのlockでは再入によるデッドロックが発生する可能性があります。 - 複数スレッドから通知される場合 → Synchronize を使用。