是Observable.Interval对高频事件有用吗?

ben*_*ben 14 c# system.reactive

我正在使用Observable.Interval来测试特定的客户端/服务器代码在不同负载下的执行情况.

但它似乎有一些奇怪的行为.

  • Observable.Interval(timespan = 0)尽可能快地产生事件,例如每秒800万个事件.这似乎没问题.
  • Observable.Interval(0 < timespan < 1ms) 只产生1个事件,然后什么都没有.
  • Observable.Interval(1ms <= timespan) 以大约所请求的速率产生事件,量化很多,最多只有64个事件/秒.

我可以理解它不一定使用下面的高分辨率计时器,但令人困惑的是它在三个区域中具有完全不同的行为.

这是预期的行为,还是我使用它错了?如果它是预期的,那么是否有一个替代Observable.Interval来模拟Rx中的高频事件源,或者我应该自己滚动......?

一个演示行为的简短程序如下:

static void Main(string[] args)
{
    const int millisecsPerTest = 10000;

    var intervals = new[]
    {
        TimeSpan.FromTicks(0),          // 0 -> rate of 8M messages per second
        TimeSpan.FromTicks(1000),       // 0.1ms -> rate of 0
        TimeSpan.FromTicks(20000),      // 2ms -> rate of 64 messages per second (not 500 as expected)
        TimeSpan.FromTicks(1000000),    // 100ms -> rate of 9 messages per second
    };

    foreach(var interval in intervals)
    {
        long msgs = 0;
        using (Observable.Interval(interval).Subscribe(
            l => { ++msgs; },
            e => Console.WriteLine("Error {0}", e.Message),
            () => Console.WriteLine("Completed")))
        {
            Thread.Sleep(millisecsPerTest);
        }

        Console.WriteLine("Interval: {0} ticks, Events: {1}, Rate: {2} events per second", interval.Ticks, msgs, (int)(msgs/(double)millisecsPerTest*1000));
    }
}
Run Code Online (Sandbox Code Playgroud)

Bra*_*don 6

是的我认为.net框架计时器使用的时钟只能以16ms的间隔运行,因此您的结果不会让我感到惊讶.虽然你的1滴答间隔测试听起来像一个bug.您使用的是什么操作系统,Rx版本.Net版本?我会看看能不能解决这个问题.

对于0刻度情况,我认为您获得了高吞吐量,因为Rx调度程序正在检测工作是"现在",并且只是立即启动它并绕过.Net计时器来安排工作.

使用Observable.Create来创建自己的Interval版本相当容易,它使用更高分辨率的计时器.稍微复杂但最终更有用的是编写一个使用高分辨率计时器的新IScheduler实现.然后,您可以将该调度程序传递给所有现有的与时间相关的Rx方法.