Reputation: 103740
Given the following RX code:
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();
}
If I run this code, the output after 30 seconds (on my machine) is ~1924, which is kind of surprising to me. I would have expected that with a delay of one millisecond, after 30 seconds the number should be closer to ~30,000. It must be something obvious, but what am I missing here?
Upvotes: 1
Views: 197
Reputation: 51329
@afrischke is right. It appears to be related to the use of a System.Timers.Timer
behind the scenes to schedule the Generations when you don't specify another Scheduler. Initially, I got the same results as you, and I noted in particular that it was not generating any sort of measurable CPU activity. When I change the code to the following, I (probably not surprisingly) get a significantly larger number:
var generator = Observable.Generate(0, i => true, i => 1, i => 1, i => TimeSpan.FromTicks(1));
var disposable = generator.Subscribe(i => Interlocked.Increment(ref x));
I think that what is happening is that the Observable is obeying the letter of the law- it is scheduling the next Generation for at least a millisecond away, but no sooner. In practice, this turns out to actually be more like 10ms away.
Upvotes: 2
Reputation: 3866
I think you are forgetting that the Windows operating system doesn't give you a hard guarantee that the generating and/or observing thread will be scheduled to run within the next millisecond. Depending on the state of your system some overhead wrt to context switching might be involved as well. On my rusty old laptop I didn't manage to get below ~20 ms. (I measured the time between invocations of the "Subscribe" lambda with the help of a Stopwatch
.)
Upvotes: 4