C# 是可观察的。间隔对高频事件有用吗?

C# 是可观察的。间隔对高频事件有用吗?,c#,system.reactive,C#,System.reactive,我使用Observable.Interval来测试特定的客户机/服务器代码在不同负载下的性能 但它似乎有一些奇怪的行为 Observable.Interval(timespan=0)尽可能快地生成事件,例如每秒生成800万个事件。这似乎还可以 可观察。间隔(0

我使用Observable.Interval来测试特定的客户机/服务器代码在不同负载下的性能

但它似乎有一些奇怪的行为

  • Observable.Interval(timespan=0)
    尽可能快地生成事件,例如每秒生成800万个事件。这似乎还可以
  • 可观察。间隔(0
    只产生一个事件,然后什么也不产生

  • Observable.Interval(1ms是的,我认为.net framework计时器使用的时钟的工作时间间隔仅为16ms左右,因此您的结果不会让我感到惊讶。尽管您的1次间隔测试听起来像是一个bug。您使用的是什么OS、Rx版本、.net版本?我会看看是否可以重新设置该问题

    对于0滴答的情况,我认为您获得了高吞吐量,因为Rx调度程序检测到工作“现在”到期,并且只是立即启动它并绕过.Net计时器来调度工作


    使用Observable相当容易。Create可创建您自己的Interval版本,该版本使用更高分辨率的计时器。更复杂但最终更有用的是编写一个使用高分辨率计时器的新ISScheduler实现。然后您可以将该调度器传递给所有现有的与时间相关的Rx方法。

    相关:或者,您可以创建一个
    调度程序
    并将其传递给
    可观察的.Interval
    。调度程序负责处理执行的时间和地点。重新写入
    可观察的。计时器
    会有点过了头,因为您无论如何都需要实现
    调度程序
    功能。我使用的是Windows 7 x64、.NET4。5和Rx 2.2.16ms分辨率当然可以解释量化和每秒64的最大速率。正如您所说,1到9999个滴答之间的行为可能是一个错误(尽管考虑到计时器分辨率,这不是一个非常实用的用例).现在我只是在创建我自己的可观察对象…我想看看使用高分辨率计时器的
    IScheduler
    的实现。@JimBolla-你是说使用类似
    秒表的东西吗?是的,我想困难在于如何“等待”。它可能包括使用常规计时器等待,直到你接近目标,然后使用高分辨率计时器旋转,直到实际指定的时间。如果我本周找到一些空闲时间,我会看看是否可以写一个要点。
    
    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));
        }
    }