我的代码与此类似。
IPruduceDemUpdates.Subscribe(update => DoUpdate(update));
但我想做的就是那样。
IPruduceDemUpdates.Subscribe(update => if(NoDoUpadteIsRunning) DoUpdate(update));
如果更新方法已在运行,则忽略传入更新。 此外,它应始终执行上次更新。无论是流的最后更新还是最后一段时间的更新。这是一个示例时间表
我有跳过的解决方案
IPruduceDemUpdates.Subscribe(update =>
{
if (_task == null || _task.IsCompleted || _task.IsCanceled || _task.IsFaulted)
_task = DoUpdate(update);
});
但我不知道如何确定,最后一次更新将会处理。
答案 0 :(得分:3)
如果DoUpdate
是同步的(在这种情况下似乎是),则可以使用Rxx中的BufferIntrospective
。它完全符合您的要求:
IProduceDemUpdates
.BufferIntrospective()
.Where(items => items.Count > 0) // ignore empty buffers
.Select(items => items[items.Count - 1]) // ignore all but last item in buffer
.Subscribe(DoUpdate);
答案 1 :(得分:2)
我参加派对有点晚了,但是这里有一条单行方式可以做到这一点。带有Sample
的{{1}}将不断对源进行抽样并始终推送上次更新 - 为了完成这项工作,您需要为TimeSpan.Zero
提供自己的线程,以便采样源可以不间断地运行:
Sample
线程被重用每个订阅者到IProduceDemUpdates.Sample(TimeSpan.Zero, NewThreadScheduler.Default)
.Subscribe(DoUpdate);
未生成每个事件 - 所以不必担心创建一大堆线程。你也可以做Sample
。关键是订阅者正在.Sample(TimeSpan.Zero, new EventLoopScheduler())
正在采样的同一线程上发送事件,以便Sample
不会对订阅者完成下一个事件进行采样。
以下代码:
Sample
通常输出:
// emits 0,1,2,3,4,5,6,7,8,9
var source = Observable.Interval(TimeSpan.FromSeconds(1)).Take(10);
source.Sample(TimeSpan.Zero, NewThreadScheduler.Default).Subscribe(x => {
Console.WriteLine(x);
Task.Delay(TimeSpan.FromSeconds(3)).Wait();
});
为了说服自己最后一次更新,请尝试:
0
2
5
9
将输出:
// emit 0,1,2
var source = Observable.Interval(TimeSpan.FromSeconds(1)).Take(3);
source.Sample(TimeSpan.Zero, NewThreadScheduler.Default).Subscribe(x => {
Console.WriteLine(x);
Task.Delay(TimeSpan.FromSeconds(10)).Wait();
});
无论您的方法是什么,请注意在附加到0
2
的订阅者的同步链中完成最慢操作的重要性。如果您的下游具有异步订阅(例如Sample
),其中包含较慢的运算符,那么您只需将反压转移到其他地方。