我需要一种方法来获取添加到符合特定条件的ReplaySubject的最新项目。下面的示例代码完成了我需要它做的事情,但它感觉不像正确的方法:
static void Main(string[] args)
{
var o = new ReplaySubject<string>();
o.OnNext("blueberry");
o.OnNext("chimpanzee");
o.OnNext("abacus");
o.OnNext("banana");
o.OnNext("apple");
o.OnNext("cheese");
var latest = o.Where(i => i.StartsWith("b"))
.Latest().First();
Console.WriteLine(latest);
Console.WriteLine("Press any key to exit");
Console.ReadKey();
}
输出:
banana
Press any key to exit
最初,我尝试使用.Where().TakeLast(1)
;但是,我现在从之前的question了解到,在OnComplete()
返回任何内容之前,您必须就该主题致电TakeLast()
。调用OnComplete()
对我来说不是一个选项,因为我需要保持此流畅通。
任何人都可以验证这是否是我想要完成的最有效的方法吗?谢谢!
修改的
请注意,我正在使用Reactive Extensions,IEnumerable代码示例将不起作用。
更新
我倾向于以下代码,因为我认为它是非阻塞的,除非有人能以不同的方式告诉我:
var latest = o.Where(i => i.StartsWith("b")).Replay(1);
using (latest.Connect())
latest.Subscribe(Console.WriteLine);
答案 0 :(得分:3)
您可以考虑使用BehaviorSubject<string>
。缺点是你必须在开始时订阅,但这可能是你想要做的。这应该为您提供所需的隔离。
var o = new ReplaySubject<string>();
var bs = new BehaviorSubject<string>(default(string));
o.Where(i => i.StartsWith("b")).Subscribe(bs);
o.OnNext("blueberry"); Console.WriteLine(bs.First());
o.OnNext("chimpanzee"); Console.WriteLine(bs.First());
o.OnNext("abacus"); Console.WriteLine(bs.First());
o.OnNext("banana"); Console.WriteLine(bs.First());
o.OnNext("apple"); Console.WriteLine(bs.First());
o.OnNext("cheese"); Console.WriteLine(bs.First());
输出:
blueberry
blueberry
blueberry
banana
banana
banana
答案 1 :(得分:0)
只要您对使用这些阻塞运算符(它看起来像你)感到高兴,我会考虑使用MostRecent运算符。
static void Main(string[] args)
{
var o = new ReplaySubject<string>();
o.OnNext("blueberry");
o.OnNext("chimpanzee");
o.OnNext("abacus");
o.OnNext("banana");
o.OnNext("apple");
o.OnNext("cheese");
var latest = o.Where(i => i.StartsWith("b"))
.MostRecent("SomeDefaultValue")
.First();
Console.WriteLine(latest);
Console.WriteLine("Press any key to exit");
Console.ReadKey();
}