给定以下RX代码:
static void Main(string[] args)
{
int x = 0;
const int timerMilliseconds = 1000 * 30; //30 seconds
var disposable = Observable.Generate(0, i => true, i => 1, i => 1, i => TimeSpan.FromMilliseconds(1))
.Subscribe(i => Interlocked.Increment(ref x));
var timer = new Timer(o =>
{
disposable.Dispose();
Console.WriteLine("Disposed of observable. Current total: " + x);
}, null, timerMilliseconds, timerMilliseconds);
Console.ReadKey(true);
timer.Dispose();
}
如果我运行这个代码,30秒后(在我的机器上)的输出约为1924,这让我有点惊讶。我本以为延迟一毫秒,30秒之后的数字应该接近约30000。这一定是显而易见的,但我在这里错过了什么?
我想您已经忘记了Windows操作系统并不能保证生成和/或观察线程将在下一毫秒内运行。根据系统的状态,可能还会涉及到一些从wrt到上下文的切换开销。在我那台锈迹斑斑的旧笔记本电脑上,我没能达到20毫秒以下。(我在Stopwatch
的帮助下测量了"订阅"lambda调用之间的时间。)
@afrischke是对的。这似乎与在未指定其他调度程序时在幕后使用System.Timers.Timer
来调度"生成"有关。最初,我得到了和您相同的结果,我特别注意到它没有产生任何可测量的CPU活动。当我将代码更改为以下代码时,我(可能并不奇怪)得到了一个明显更大的数字:
var generator = Observable.Generate(0, i => true, i => 1, i => 1, i => TimeSpan.FromTicks(1));
var disposable = generator.Subscribe(i => Interlocked.Increment(ref x));
我认为正在发生的事情是,Observable遵守了法律的条文——它将下一代的时间安排在至少一毫秒之外,但不会更早。在实践中,这实际上更像是10毫秒之外。