【问题标题】:How to get the latest value from a ReplaySubject<T> before completion如何在完成之前从 ReplaySubject<T> 获取最新值
【发布时间】:2011-07-21 19:48:15
【问题描述】:

我需要一种方法来获取添加到符合特定条件的 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 知道,您必须在TakeLast() 将返回任何内容之前就该主题调用OnComplete()。调用 OnComplete() 对我来说不是一个选项,因为我需要保持这个流打开。

谁能验证这是否是我想要完成的最有效的方法?谢谢!

编辑

请注意,我正在使用响应式扩展,IEnumerable 代码示例将无法正常工作。

更新

我倾向于使用以下代码,因为我相信它是非阻塞的,除非有人能以不同的方式告诉我:

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

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

【问题讨论】:

  • @kevin:对不起,我可能遗漏了一些东西,但我看不出您发布的链接与我的情况有何关联。
  • 基本上我发现了一些有“类似”问题的帖子(得到“最后一个”项目)。那个表明你必须返回 2 个项目......另一个可能有帮助的项目在这里:social.msdn.microsoft.com/Forums/en-SG/rx/thread/… 但我已经超出了我的头脑,所以我现在就停下来。 3次罢工! :)
  • 请记住,使用 UPDATE 解决方案,在您调用 Connect 之前发生的任何订阅都将返回“blueberry”作为第一个值,“banana”作为第二个值。

标签: c# .net system.reactive


【解决方案1】:

您可以考虑使用BehaviorSubject&lt;string&gt;。缺点是您必须在一开始就订阅,但这可能就是您想要做的。这应该为您提供所需的隔离。

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

【讨论】:

  • 我知道我可以使用 BehaviorSubject 来实现这一点,但由于其他原因,底层流需要保持为 ReplaySubject。我什至没有想到要创建一个 BehaviorSubject 并订阅底层的 ReplaySubject。谢谢!
【解决方案2】:

只要您喜欢使用这些阻塞运算符(看起来像您),我会考虑使用 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();
}

【讨论】:

  • 我已经发布了对原始问题的修订,并提供了一种非阻塞方式来完成此操作。我基于您的原始帖子,您如此迅速地删除了它;)
  • @Matthew Glace - 是的,我删除了它,因为我对不同的结果不满意,具体取决于您连接的位置(订阅之前或之后)。不知道在这一点上是否有任何其他方式,但不想发布我不满意的东西;)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2015-07-14
  • 1970-01-01
  • 1970-01-01
  • 2021-12-20
  • 2020-08-06
  • 1970-01-01
  • 2015-07-16
相关资源
最近更新 更多