Timer
1. 概要
Timer は、指定した時間が経過した後に Unit を発行するファクトリメソッドです。period を併せて指定すると、初回発行後も一定間隔で繰り返し発行し続けます。
遅延の起点は TimeSpan(相対時間)と DateTimeOffset(絶対時刻)の両方に対応しています。
2. シグネチャ
単発(TimeSpan)
csharp
public static Observable<Unit> Timer(TimeSpan dueTime, CancellationToken cancellationToken = default)指定した TimeSpan が経過した後に Unit を 1 つ発行し、完了します。
csharp
Observable.Timer(TimeSpan.FromSeconds(3))単発(DateTimeOffset)
csharp
public static Observable<Unit> Timer(DateTimeOffset dueTime, CancellationToken cancellationToken = default)指定した絶対時刻に到達した時点で Unit を 1 つ発行し、完了します。
csharp
Observable.Timer(DateTimeOffset.UtcNow.AddMinutes(5))繰り返し(TimeSpan + period)
csharp
public static Observable<Unit> Timer(TimeSpan dueTime, TimeSpan period, CancellationToken cancellationToken = default)dueTime 経過後に最初の値を発行し、以降は period 間隔で繰り返し発行します。自動的には完了しません。
csharp
Observable.Timer(TimeSpan.FromSeconds(1), TimeSpan.FromSeconds(2))繰り返し(DateTimeOffset + period)
csharp
public static Observable<Unit> Timer(DateTimeOffset dueTime, TimeSpan period, CancellationToken cancellationToken = default)指定した絶対時刻に最初の値を発行し、以降は period 間隔で繰り返し発行します。
csharp
Observable.Timer(DateTimeOffset.UtcNow.AddSeconds(10), TimeSpan.FromSeconds(5))TimeProvider 指定バリエーション
csharp
public static Observable<Unit> Timer(TimeSpan dueTime, TimeProvider timeProvider, CancellationToken cancellationToken = default)
public static Observable<Unit> Timer(DateTimeOffset dueTime, TimeProvider timeProvider, CancellationToken cancellationToken = default)
public static Observable<Unit> Timer(TimeSpan dueTime, TimeSpan period, TimeProvider timeProvider, CancellationToken cancellationToken = default)
public static Observable<Unit> Timer(DateTimeOffset dueTime, TimeSpan period, TimeProvider timeProvider, CancellationToken cancellationToken = default)上記すべてのオーバーロードに対応する TimeProvider 指定版です。テスト時にフェイクタイマーを注入したり、独自のスケジューリングを行う場合に使用します。
オーバーロードの使い分け
| overload | 使う場面 |
|---|---|
Timer(TimeSpan) | 相対的な遅延後に 1 回だけ発行する |
Timer(DateTimeOffset) | 特定の時刻に 1 回だけ発行する |
Timer(TimeSpan, TimeSpan) | 初回遅延+周期的な繰り返し |
Timer(DateTimeOffset, TimeSpan) | 特定時刻から周期的な繰り返し |
各 TimeProvider 付き | テスト容易性の確保、カスタムスケジューラの利用 |
3. マーブルダイアグラム
単発の場合、dueTime が経過した時点で Unit を 1 つ発行し完了します。period 付きの場合、dueTime 後に最初の値を発行し、以降 period ごとに繰り返し発行し続けます。
4. サンプルコード
csharp
using R3;
// 3 秒後に 1 回だけ発行
Observable.Timer(TimeSpan.FromSeconds(3))
.Subscribe(
_ => Console.WriteLine("発火"),
_ => Console.WriteLine("完了"));
// 出力(3 秒後): 発火
// 出力: 完了
// 1 秒後に初回発行、以降 2 秒ごとに繰り返し
var cts = new CancellationTokenSource();
Observable.Timer(TimeSpan.FromSeconds(1), TimeSpan.FromSeconds(2), cts.Token)
.Subscribe(_ => Console.WriteLine($"tick: {DateTime.Now:HH:mm:ss}"));
// 出力例:
// tick: 12:00:01
// tick: 12:00:03
// tick: 12:00:05
// ...(cts.Cancel() で停止)
// DateTimeOffset で特定時刻に発行
Observable.Timer(DateTimeOffset.UtcNow.AddMinutes(1))
.Subscribe(_ => Console.WriteLine("1 分後に発火"));
// TimeProvider を指定(テスト向け)
var fakeTime = new FakeTimeProvider();
Observable.Timer(TimeSpan.FromSeconds(5), fakeTime)
.Subscribe(_ => Console.WriteLine("5 秒後"));
fakeTime.Advance(TimeSpan.FromSeconds(5));
// 出力: 5 秒後5. 補足
Interval との違い
Interval は period のみを受け取り、初回の発行も period 後に行われます。Interval(period) は Timer(period, period) と等価です。初回遅延と周期を個別に設定したい場合は Timer を使用してください。
TimerFrame との違い
実時間ではなくフレーム数で遅延や繰り返しを指定したい場合は TimerFrame を使用してください。