开发者

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

开发者 https://www.devze.com 2023-03-21 22:09 出处:网络
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:

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[] arg开发者_开发知识库s)
{
    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);


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


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

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号