C# 可观测节流
我正在尝试使用反应式扩展实现事件限制。 我有一个系统,在该系统中,特定用户或其他实体类型的事件可能会以高频率引发。 我需要的是将事件延迟特定的时间量,一旦超时过期,使用最后一个值引发事件 我所做的就是这样C# 可观测节流,c#,system.reactive,C#,System.reactive,我正在尝试使用反应式扩展实现事件限制。 我有一个系统,在该系统中,特定用户或其他实体类型的事件可能会以高频率引发。 我需要的是将事件延迟特定的时间量,一旦超时过期,使用最后一个值引发事件 我所做的就是这样 private Subject<int> userBalanceObservable = new Subject<int>(); userBalanceObservable.Sample(TimeSpan.FromSeconds(sampleSeconds))
private Subject<int> userBalanceObservable = new Subject<int>();
userBalanceObservable.Sample(TimeSpan.FromSeconds(sampleSeconds))
.Subscribe(sample => OnRaiseBalanceEvent(sample));
编辑
这种方法的问题是,为传递给OnNext的最后一个值引发事件,我实际需要的是为传递给OnNext的每个值都有一个dellay
例如OnNext(1)、OnNext(2)、OnNext(3)我需要对1,2,3进行延迟调用,而我只得到最后一个值,即3。Sample在每次达到采样间隔时发布最后一个值。如果这是你需要的行为,那就好了。查看更多信息+其他降低排放率的方法 关于您的问题的新信息: 如果要在达到某个超时后发出所有值,可以对这些值进行分组,直到达到超时为止(注意:如果由于事件发出的频率,继续添加事件而未达到超时,则可能会耗尽内存) 您可以创建一个缓冲区,该缓冲区将一直填满,直到达到
去盎司超时,有关指针,请参见SO上的此答案:不只是工作吗?唯一的“问题”是OnRaiseBalanceEvent必须使用list,而不是一个值,但计算机科学中的所有问题都可以通过另一个间接层次来解决;)
使用系统;
使用System.Collections.Generic;
使用System.Linq;
使用系统线程;
使用系统、反应、主题;
使用System.Reactive.Linq;
命名空间控制台应用程序1
{
班级计划
{
静态void Main(字符串[]参数)
{
Subject userBalanceObservable=新Subject();
userBalanceObservable.Buffer(TimeSpan.FromSeconds(2))//获取项目列表
.Subscribe(sampleList=>ProcessSamples(sampleList));
int cont=0;
而(!Console.KeyAvailable)
{
userBalanceObservable.OnNext(续);
cont++;
userBalanceObservable.OnNext(续);
cont++;
睡眠(1000);
}
}
私有静态void ProcessSamples(IList sampleList)
{
Console.WriteLine(“[{0}]”,string.Join(“,”,sampleList.ToArray());
}
}
}
实际上,它似乎并没有像我预期的那样真正起作用。我需要的是有一个样品延迟每个具体项目,而不是一般任何项目。例如OnNext(1)、OnNext(2)、OnNext(3)我希望1,2,3的调用延迟,而我只得到最后一个值,即3。被动扩展是否支持此类功能?请尝试延迟。请参阅@NullReference-这不是您在问题中要求的。你能更新这个问题吗?下次试着发布一个最小的完整的可验证示例(),这样我们就可以确切地知道你想要实现什么。理想的情况是使用单元测试。您确实需要向我们展示所有代码,尤其是OnRaiseBalanceEvent
中发生的事情,以及userBalanceObservable
如何获取其值。不过,作为一个小提示,如果你使用的是主题
,你可能做错了什么。嗯,我认为缓冲区可以完成这项工作。我可以使用.Where(x=>x.Count>0)使空序列静音,使用Distinct()只获取一个值实例。
userBalanceObservable.OnNext(userId);
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading;
using System.Reactive.Subjects;
using System.Reactive.Linq;
namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
Subject<int> userBalanceObservable = new Subject<int>();
userBalanceObservable.Buffer(TimeSpan.FromSeconds(2)) //get List of items
.Subscribe(sampleList => ProcessSamples(sampleList));
int cont = 0;
while (!Console.KeyAvailable)
{
userBalanceObservable.OnNext(cont);
cont++;
userBalanceObservable.OnNext(cont);
cont++;
Thread.Sleep(1000);
}
}
private static void ProcessSamples(IList<int> sampleList)
{
Console.WriteLine("[{0}]", string.Join(", ", sampleList.ToArray()));
}
}
}