我有一个接收事件流的类,并推出另一个事件流。
所有事件都使用Reactive Extensions(RX)。使用IObserver<T>
将传入的事件流从外部源推送到.OnNext
,并使用IObservable<T>
和.Subscribe
推出传出的事件流。我在幕后使用Subject<T>
来管理它。
我想知道RX中有哪些技术暂时暂停输出。这意味着传入事件将在内部队列中累积,当它们取消暂停时,事件将再次流出。
答案 0 :(得分:4)
这是我使用Buffer和Window运算符的解决方案:
public static IObservable<T> Pausable<T>(this IObservable<T> source, IObservable<bool> pauser)
{
var queue = source.Buffer(pauser.Where(toPause => !toPause),
_ => pauser.Where(toPause => toPause))
.SelectMany(l => l.ToObservable());
return source.Window(pauser.Where(toPause => toPause).StartWith(true),
_ => pauser.Where(toPause => !toPause))
.Switch()
.Merge(queue);
}
窗口在订阅时打开,每次都是真实的&#39;从pauser流收到。当暂停提供“假”时,它会关闭。值。
缓冲区执行它应该做的事情,缓冲介于&#39; false&#39;之间的值。并且&#39; true&#39;来自pauser。缓冲区收到“真实”后它输出立即流式传输的IList值。
DotNetFiddle链接:https://dotnetfiddle.net/vGU5dJ
答案 1 :(得分:2)
这是一种相当简单的Rx方式来做你想要的。我创建了一个名为Pausable
的扩展方法,它接受一个源可观察源,另一个可观察到boolean
,它暂停或恢复了可观察量。
public static IObservable<T> Pausable<T>(
this IObservable<T> source,
IObservable<bool> pauser)
{
return Observable.Create<T>(o =>
{
var paused = new SerialDisposable();
var subscription = Observable.Publish(source, ps =>
{
var values = new ReplaySubject<T>();
Func<bool, IObservable<T>> switcher = b =>
{
if (b)
{
values.Dispose();
values = new ReplaySubject<T>();
paused.Disposable = ps.Subscribe(values);
return Observable.Empty<T>();
}
else
{
return values.Concat(ps);
}
};
return pauser.StartWith(false).DistinctUntilChanged()
.Select(p => switcher(p))
.Switch();
}).Subscribe(o);
return new CompositeDisposable(subscription, paused);
});
}
可以像这样使用:
var xs = Observable.Generate(
0,
x => x < 100,
x => x + 1,
x => x,
x => TimeSpan.FromSeconds(0.1));
var bs = new Subject<bool>();
var pxs = xs.Pausable(bs);
pxs.Subscribe(x => { /* Do stuff */ });
Thread.Sleep(500);
bs.OnNext(true);
Thread.Sleep(5000);
bs.OnNext(false);
Thread.Sleep(500);
bs.OnNext(true);
Thread.Sleep(5000);
bs.OnNext(false);
现在,我唯一不能理解你的“传入的事件流是什么意思IObserver<T>
”。流是IObservable<T>
。观察者不是溪流。听起来你在这里没有做点什么。你能加入你的问题并进一步解释吗?
答案 2 :(得分:1)
您可以使用value
模拟暂停/取消暂停。
一旦您的pauseObservable发出'暂停'值,缓冲事件直到pauseObservable发出'unpaused'值。
以下是一个使用BufferUntil implementation by Dave Sexton和Observable logic by Timothy Shields的例子(前一段时间我自己的问题)
for key, result in cb.get_multi(keys).items():
print "Value is", result.value
改进空间:可能将两个订阅源(pausedEvents和notPausedEvents)合并为一个。