我有一个观察我正在订阅。这个obsevable将返回一个对象,该对象具有一个名为ActivationType的属性,可以多次设置。
我想要实现的是在ActivationType设置为“Type1”时记录消息。但是,如果ActivationType设置为“Type2”,则只记录一次消息并等待30秒再次登录,如果ActivationType为“Type2”。
所以,如果我有:
myObservable
.Where(o => o.ActivationType == "Type1" || o.ActivationType == "Type2") //listen for types 1 and 2
.Throttle() // ??? somehow only throttle if we are currently looking at Type2
.Subscribe(Log); //log some stuff
我相信Throttle()是我正在寻找的,但我不确定如何有条件地触发它。
有什么建议吗?
答案 0 :(得分:6)
啊,对于几乎不可能理解的Window
运营商而言,这是一个完美的案例!
编辑:
我发布这个链接就像一个月十几次,我发誓 - 最好的直读我见过Window
,Join
,Buffer
,GroupJoin
等。操作符:
Lee Campbell: Rx Part 9–Join, Window, Buffer and Group Join
var source = new Subject<Thing>();
var feed = source.Publish().RefCount();
var ofType1 = feed.Where(t => t.ActivationType == "Type1");
var ofType2 = feed
// only window the type2s
.Where(t => t.ActivationType == "Type2")
// our "end window selector" will be a tick 30s off from start
.Window(() => Observable.Timer(TimeSpan.FromSeconds(30)))
// we want the first one in each window...
.Select(lst => lst.Take(1))
// moosh them all back together
.Merge();
// We want all "type 1s" and the buffered outputs of "type 2s"
var query = ofType1.Merge(ofType2);
// Let's set up a fake stream of data
var running = true;
var feeder = Task.Factory.StartNew(
() => {
// until we say stop...
while(running)
{
// pump new Things into the stream every 500ms
source.OnNext(new Thing());
Thread.Sleep(500);
}
});
using(query.Subscribe(Console.WriteLine))
{
// Block until we hit enter so we can see the live output
// from the above subscribe
Console.ReadLine();
// Shutdown our fake feeder
running = false;
feeder.Wait();
}
答案 1 :(得分:2)
为什么不直接使用两个流?
var baseStream = myObservable.Publish().RefCount(); // evaluate once
var type1 = baseStream.Where(o => o.ActivationType == "Type1");
var type2 = baseStream.Where(o => o.ActivationType == "Type2").Throttle(TimeSpan.FromSeconds(30));
type1.Merge(type2).Subscribe(Log);