How to get the latest value from a ReplaySubject<T> before completion

喜欢而已 提交于 2019-12-12 12:07:42

问题


I need a way of grabbing the most recent item added to a ReplaySubject that matches certain criteria. The sample code below does what I need it to do but it doesn't feel like the correct approach:

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

Output:

banana
Press any key to exit

Initially, I tried using .Where().TakeLast(1); however, I now know from a previous question that you must call OnComplete() on the subject before TakeLast() will return anything. Calling OnComplete() is not an option for me because I need to keep this stream open.

Can anyone please validate whether this is the most effective approach to what I'm trying to accomplish? Thanks!

EDIT

Please note that I'm using Reactive Extensions and IEnumerable code samples will not work.

UPDATE

I'm leaning towards the following code because I believe it is non-blocking unless anyone can tell me differently:

var latest = o.Where(i => i.StartsWith("b")).Replay(1);

using (latest.Connect())
     latest.Subscribe(Console.WriteLine);

回答1:


You may consider using BehaviorSubject<string>. The drawback is that you have to subscribe at the beginning but that is probably what you want to do anyway. This should provide you with isolation you need.

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());

Output:

blueberry
blueberry
blueberry
banana
banana
banana



回答2:


So long as your happy using these blocking operators (which it looks like you are) I'd look into using the MostRecent operator.

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


来源:https://stackoverflow.com/questions/6762163/how-to-get-the-latest-value-from-a-replaysubjectt-before-completion

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!