Skip to content

Timeout

1. 概要

Timeout は、ソースシーケンスから前回の値(または購読開始)以降、指定した時間内に新しい値が届かなかった場合に TimeoutException でシーケンスを完了させるオペレーターです。

ネットワークリクエストの応答監視やセンサーデータの死活監視など、一定時間内にデータが届くことを保証したい場合に使用します。

2. シグネチャ

TimeSpan によるタイムアウト

csharp
public static Observable<T> Timeout<T>(
    this Observable<T> source,
    TimeSpan dueTime)

前回の値(または購読開始)から dueTime 以内に次の値が届かなかった場合、TimeoutException で完了します。

csharp
source.Timeout(TimeSpan.FromSeconds(5))

TimeSpan + TimeProvider によるタイムアウト

csharp
public static Observable<T> Timeout<T>(
    this Observable<T> source,
    TimeSpan dueTime,
    TimeProvider timeProvider)

TimeProvider を指定してタイマーの実装を差し替えられます。テスト時に FakeTimeProvider を使用して時間を手動制御できます。

csharp
source.Timeout(TimeSpan.FromSeconds(5), fakeTimeProvider)

overload の使い分け

overload使う場面
TimeSpan通常のタイムアウト監視
TimeSpan, TimeProviderユニットテストで時間を制御したい場合

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

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

各値が発行されるたびにタイマーがリセットされます。指定時間内に次の値が届けばタイマーがリセットされ、シーケンスは続行されます。指定時間内に値が届かなかった場合、TimeoutException でシーケンスが完了します。

4. サンプルコード

csharp
using R3;

// API レスポンスを 10 秒でタイムアウト
apiResponseObservable
    .Timeout(TimeSpan.FromSeconds(10))
    .Subscribe(
        response => HandleResponse(response),
        error =>
        {
            if (error is TimeoutException)
            {
                Console.WriteLine("タイムアウトしました");
            }
        });

// センサーデータの死活監視
sensorDataObservable
    .Timeout(TimeSpan.FromSeconds(30))
    .Subscribe(
        data => ProcessData(data),
        error => AlertSensorFailure());

// FakeTimeProvider を使ったテスト
var fakeTime = new FakeTimeProvider();
Exception? caughtError = null;

var subject = new Subject<int>();
subject
    .Timeout(TimeSpan.FromSeconds(5), fakeTime)
    .Subscribe(
        x => { },
        error => caughtError = error);

subject.OnNext(1);
fakeTime.Advance(TimeSpan.FromSeconds(3));
subject.OnNext(2);  // タイマーリセット
fakeTime.Advance(TimeSpan.FromSeconds(5));
// caughtError は TimeoutException