从每个区间的可观察值中取N个值

时间:2015-03-08 21:38:50

标签: c# system.reactive

我有一个observable,它为每个ms传输一个值。 ,这是每250毫秒完成的。 (意思是250毫秒内的250个值(给予或接受))。

模拟示例代码:

     IObservable<IEnumerable<int>> input = from _ in Observable.Interval(TimeSpan.FromMilliseconds(250))
                    select CreateSamples(250);

      input.Subscribe(values =>
        {
            for (int i = 0; i < values.Count(); i++)
            {
                Console.WriteLine("Value : {0}", i);
            }
        });

        Console.ReadKey(); 


    private static IEnumerable<int> CreateSamples(int count)
    {
        for (int i = 0; i < 250; i++)
        {
            yield return i;
        }
    }

我需要的是创建某种形式的过程可观察对象,它以每33毫秒8个值的速率处理输入可观察量

有关这方面的内容:

 IObservable<IEnumerable<int>> process = from _ in Observable.Interval(TimeSpan.FromMilliseconds(33)) 
                     select stream.Take(8);

我想知道两件事:

1)如何用反应扩展提供的内置运算符编写第一个样本?

2)如何创建从输入流中获取值的流程流    哪种行为有什么描述?

我尝试使用Window作为以下评论的建议。

 input.Window(TimeSpan.FromMilliseconds(33)).Take(8).Subscribe(winObservable => Debug.WriteLine(" !! "));

好像我得到了8个且只有8个未知数量的可观察值

我需要的是每33毫秒重复8个值。从输入可观察到。

上面的代码是8个可观察的IEnumrable,然后闲置。

编辑:感谢詹姆斯世界。这是一个样本。

  var input = Observable.Range(1, int.MaxValue);

  var timedInput = Observable.Interval(TimeSpan.FromMilliseconds(33))
        .Zip(input.Buffer(8), (_, buffer) => buffer);

  timedInput.SelectMany(x => x).Subscribe(Console.WriteLine);

但是现在我需要计算缓冲区值 我需要通过间隔之间传递的实际MS完成此操作 当你写一个 TimeSpan.FromMilliseconds(33)时,计时器的Interval事件实际上会在45毫秒左右提出或接受。

有没有办法计算缓冲区,比如 PSUDO

  input.TimeInterval().Buffer( s => s.Interval.Milliseconds / 4)

2 个答案:

答案 0 :(得分:3)

由于.NET计时器分辨率为15毫秒,因此无法通过合理的解决方案以任何精度执行此操作。

如果计时器 足够快,则必须使用起搏器展平并重新打包流,例如:

// flatten stream
var fs = input.SelectMany(x => x);

// buffer 8 values and release every 33 milliseconds
var xs = Observable.Interval(TimeSpan.FromMilliseconds(33))
                   .Zip(fs.Buffer(8), (_,buffer) => buffer);

虽然正如我所说,这会给人一种非常紧张的时机。如果这种时间分辨率对你很重要,那就去当地吧!

答案 1 :(得分:1)

我同意詹姆斯的分析。

我想知道这个查询是否能给你带来更好的结果:

IObservable<IList<int>> input =
    Observable
        .Generate(
            0,
            x => true,
            x => x < 250 ? x + 1 : 0,
            x => x,
            x => TimeSpan.FromMilliseconds(33.0 / 8.0))
        .Buffer(TimeSpan.FromMilliseconds(33.0));