C#(.NET 4.0)アプリケーションでは、Reactive Extensions(2.0.20823.0)を使用して、イベントを集計値にグループ化するための時間境界を生成します。結果のデータベースへのクエリを簡素化するために、これらの境界線は完全な時間(または下の例では秒)に整列する必要があります。Observable.Timer():タイマードリフトを回避するにはどうすればよいですか?
var time = DefaultScheduler.Instance;
var start = new DateTimeOffset(time.Now.DateTime, time.Now.Offset);
var span = TimeSpan.FromSeconds(1);
start -= TimeSpan.FromTicks(start.Ticks % 10000000);
start += span;
var boundary = Observable.Timer(start, span, time);
boundary.Select(i => start + TimeSpan.FromSeconds(i * span.TotalSeconds))
.Subscribe(t => Console.WriteLine("ideal: " + t.ToString("HH:mm:ss.fff")));
boundary.Select(i => time.Now)
.Subscribe(t => Console.WriteLine("actual: " + t.ToString("HH:mm:ss.fff")));
あなたが意図していることがわかりますし、タイマーの実際の時間が非常に大きく離れて漂流ティック:
ideal: 10:06:40.000
actual: 10:06:40.034
actual: 10:06:41.048
ideal: 10:06:41.000
actual: 10:06:42.055
ideal: 10:06:42.000
ideal: 10:06:43.000
actual: 10:06:43.067
actual: 10:06:44.081
ideal: 10:06:44.000
ideal: 10:06:45.000
actual: 10:06:45.095
actual: 10:06:46.109
ideal: 10:06:46.000
ideal: 10:06:47.000
actual: 10:06:47.123
actual: 10:06:48.137
ideal: 10:06:48.000
...
私もHistoricalScheduler
の、そしてもちろん使用することObservable.Timer()
を使用して
私はそこに問題がない。私はわずかな不正確さを許容することができ、私はシステムクロックの変更を気にする必要はありません。 Observablesによってトリガされる重量操作はありません。
また、blog postにRXタイマーのドリフトの問題についての長い議論があることは知っていますが、私はその周りを頭で囲むことができないようです。
体系的なタイマードリフトなしでObservable
を定期的にスケジュールする正しい方法は何でしょうか?
ありがとう、素晴らしい答えと私の問題を解決するために十分正確です。面白いことに、Observable.Generate()が[関連するシナリオ]で頭痛を与えているので、私はすでにそれを排除していました(http://stackoverflow.com/questions/13462713/why-does-observable-generate-throw-システムスタックオーバーフロー例外)。私はRXに関する質問をするたびに私のハードウェアをよく知るように思えます:-) –
RXソースのコメントを指摘してくれてありがとう。私はもっと頻繁にそれらをチェックアウトする必要があるように見える、今すぐ利用可能です。 –