Как получить последнее значение из ReplaySubject <T>до завершения - PullRequest
4 голосов
/ 20 июля 2011

Мне нужен способ получения самого последнего элемента, добавленного в объект воспроизведения, который соответствует определенным критериям.Пример кода ниже делает то, что мне нужно, но это не похоже на правильный подход:

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);однако теперь я знаю из предыдущего вопроса , что вы должны позвонить OnComplete() по этому вопросу, прежде чем TakeLast() вернет что-либо.Вызов OnComplete() для меня не вариант, потому что мне нужно держать этот поток открытым.

Может ли кто-нибудь подтвердить, является ли это наиболее эффективным подходом к тому, чего я пытаюсь достичь?Спасибо!

РЕДАКТИРОВАТЬ

Обратите внимание, что я использую Reactive Extensions и IEnumerable примеры кода не будут работать.

ОБНОВЛЕНИЕ

Я склоняюсь к следующему коду, потому что считаю, что он неблокирующий, если кто-то не скажет мне по-другому:

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

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

Ответы [ 2 ]

3 голосов
/ 21 июля 2011

Вы можете рассмотреть возможность использования 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
0 голосов
/ 20 июля 2011

Пока вы счастливы, используя эти блокирующие операторы (которые выглядят так, как вы), я бы хотел использовать оператор 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();
}
...