我正在尝试使用响应式扩展来实现事件限制。 我有一个系统,可能会针对特定用户或其他实体类型以高频率引发事件。 我需要的是延迟事件特定的时间量,一旦超时到期,用最后一个值提升事件。
我所做的就是这个
private Subject<int> userBalanceObservable = new Subject<int>();
userBalanceObservable.Sample(TimeSpan.FromSeconds(sampleSeconds))
.Subscribe(sample => OnRaiseBalanceEvent(sample));
事件发生时
userBalanceObservable.OnNext(userId);
修改
这种方法的问题是为传递给OnNext的最后一个值引发了事件,我真正需要的是为传递给OnNext的每个值都有一个dellay。
例如OnNext(1),OnNext(2),OnNext(3)我需要延迟调用1,2,3而不是我只获得最后一个值3。
答案 0 :(得分:1)
每次尝试采样间隔时,样本都会发布最后一个值。如果这是你需要的行为,那就没关系。请查看http://www.introtorx.com/content/v1.0.10621.0/13_TimeShiftedSequences.html#Sample了解更多信息以及其他降低排放率的方法。
关于您的问题的新信息:
如果要在达到某个超时后发出所有值,您可以对这些值进行分组,直到超时达到(注意:如果您继续添加事件而没有因为频率超时而超时,则可能会耗尽内存事件排放)
您可以创建一个填充缓冲区,直到Debounce
超时命中,请参阅SO上的答案以获取指针:How to implement buffering with timeout in RX
答案 1 :(得分:1)
不只是buffering有效吗?唯一的“问题”是OnRaiseBalanceEvent必须使用list而不是一个值,但计算机科学中的所有问题都可以通过另一个间接层来解决;)
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()));
}
}
}