Observable.Generate не генерирует так быстро, как я ожидал.Что мне не хватает? - PullRequest
1 голос
/ 02 февраля 2012

Учитывая следующий код 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. Это должно быть что-то очевидное, но чего мне здесь не хватает?

Ответы [ 2 ]

4 голосов
/ 02 февраля 2012

Я думаю, вы забыли, что операционная система Windows не дает вам твердой гарантии того, что поток генерации и / или наблюдения будет запущен в течение следующей миллисекунды.В зависимости от состояния вашей системы также могут потребоваться некоторые накладные расходы на переключение контекста.На моем ржавом старом ноутбуке мне не удалось получить значение ниже ~ 20 мс.(Я измерил время между вызовами лямбды «Подписаться» с помощью Stopwatch.)

2 голосов
/ 02 февраля 2012

@ afrischke прав. Похоже, это связано с использованием System.Timers.Timer за кулисами для планирования поколений, когда вы не указываете другой планировщик. Первоначально я получил те же результаты, что и вы, и, в частности, я отметил, что он не генерирует какой-либо измеримой активности процессора. Когда я изменяю код на следующий, я (вероятно, не удивительно) получаю значительно большее число:

var generator = Observable.Generate(0, i => true, i => 1, i => 1, i => TimeSpan.FromTicks(1));
var disposable = generator.Subscribe(i => Interlocked.Increment(ref x));

Я думаю, что происходит то, что Наблюдаемая подчиняется букве закона - она ​​планирует следующее поколение на по крайней мере в миллисекунде, но не раньше. На практике это оказывается больше на расстоянии 10 мс.

...