0

I have a server that receives batches of signal samples from clients. Each batch can contain up to 1000 samples and be received once per second (1000 Hz). Once I have received the samples, I want to publish them locally via an Observable at the same frequency they were generated from the signal source device. I have put together the following concept code that accomplishes what I want to do.

LINQPad code:

var frequency = 1000; // samples / second
int sampleCount = 1000;
var samples = Enumerable.Range(1, sampleCount).ToArray();

ManualResetEvent done = new ManualResetEvent(false);
int count = 0;
Stopwatch sw = new Stopwatch();
sw.Start();

samples.ToObservable()
    .Do(_ => Thread.Sleep(1000/frequency))
    .Subscribe((next) => count++, () => { sw.Stop(); done.Set(); });

done.WaitOne();

sw.ElapsedMilliseconds.Dump("Subscription duration");
count.Dump("Items observed");

I tried other ways to simulate the delay between samples, but at such high frequencies, any timer-based or task-based approaches apparently had too much overhead to keep up. So my question(s) are:

  1. Is this the best approach to delaying a high frequency observable?
  2. In the Do(...) method, it is the 'SubscribeOn' thread that I am putting to sleep, right?
  3. Should I explicitly be calling the SubscribeOn() and ObserveOn() method to help ensure that the observer code does not interfere with publishing of the samples?

Thanks in advance!

Casey Chester
  • 268
  • 3
  • 11
  • FYI, something that occurs once per minute is not 1000 Hz. It's 0.17 Hz (1 / 60 seconds). – user2023861 May 06 '14 at 14:38
  • Your absolutely right. I meant to say 'batch of 1000 samples received once per second' (not per minute). Will edit question to correct. Thanks for the heads up. – Casey Chester May 06 '14 at 15:36
  • See [this answer](http://stackoverflow.com/a/13840513/337065), the interrupt rate is 15.6ms so you're going to have trouble with anything more frequent that that. – Matthew Finlay May 06 '14 at 22:13
  • 1
    @MatthewFinlay Unless we use a dedicated thread + spin-wait... that might be capable of yielding at a higher rate. That'll just waste cycles, though... This kind of thing isn't really what Rx (or C# for that matter) was designed for, I don't think... – cwharris May 07 '14 at 15:46
  • @MatthewFinlay Yes - I have already witnessed this in testing. If I substitute the Thread.Sleep in the sample code provided with a Task.Delay(1 ms).Wait() then I go from processing 1000 items in 'just over' 1 second to 1000 items in 'right around' 15.6 seconds. This result is right in line with the answer you provided (15 ms X 1000 items ~= 15 seconds). – Casey Chester May 07 '14 at 16:12

0 Answers0