如何在完成之前从ReplaySubject <t>获取最新值</t>

时间:2011-07-20 12:49:10

标签: c# .net system.reactive

我需要一种方法来获取添加到符合特定条件的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);

2 个答案:

答案 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();
}