在 C# (.NET 4.0) 应用程序中,我使用响应式扩展 (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
...
我也使用 a HistoricalScheduler
,当然我在那里没有问题。我可以容忍轻微的不准确,我不需要关心系统时钟的变化。这些 Observable 不会触发重量级操作。
另外,我知道在这篇博文中对 RX 定时器漂移问题进行了冗长的讨论,但我似乎无法理解它。
定期安排Observable
没有系统的计时器漂移的正确方法是什么?