我有一个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)
答案 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));