[英]Is Observable.Interval useful for high frequency events?
我正在使用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));
}
}
是的我认为.net框架计时器使用的时钟只能以16ms的间隔运行,因此您的结果不会让我感到惊讶。 虽然你的1滴答间隔测试听起来像一个bug。 您使用的是什么操作系统,Rx版本.Net版本? 我会看看能不能解决这个问题。
对于0刻度情况,我认为你获得了高吞吐量,因为Rx调度程序正在检测工作是“现在”,并且只是立即启动它并绕过.Net计时器来安排工作。
使用Observable.Create来创建自己的Interval版本相当容易,它使用更高分辨率的计时器。 稍微复杂但最终更有用的是编写一个使用高分辨率计时器的新IScheduler实现。 然后,您可以将该调度程序传递给所有现有的与时间相关的Rx方法。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.