System.Reactive可观察到的字符串将项目组合成单个项目,作为新的Observable

时间:2018-12-06 18:11:21

标签: c# observable system.reactive

我有一个Observable,其项目发出的字符串值只是我要公开提供为Observable的整个消息的一部分。

如果物品是这样进来的:

  • "This is "
  • "only part of"
  • " the message."

我想提供一个公共的可观察到的东西,其发射出的像是:

  • "This is only part of the message."

我知道消息的结尾部分何时是完整的消息。

我一直在尝试使Buffer运算符起作用,因为这似乎是我的情况的正确运算符,但是我不知道如何告诉缓冲区关闭条件是什么,或者甚至是关闭条件。可能。

1 个答案:

答案 0 :(得分:3)

Buffer是执行此操作的最佳方法:

var source = new Subject<string>();

var result = source.Publish(_source => _source
        .Buffer(_source.Where(s => s.EndsWith(".")))
    )
    .Select(l => l.Aggregate ((x, y) => x + y));

result.Subscribe(s => Console.WriteLine(s));

source.OnNext("This is ");
source.OnNext("only part of");
source.OnNext(" the message.");
source.OnNext("Not. A. Full. Message ");
source.OnNext("but end of stream anyway");
source.OnCompleted();

Buffer带有一个参数,该参数指定应在何处进行组拆分,该参数由where子句指定。 Buffer将邮件汇总到一个列表中,然后再与Linq的汇总汇总。


编辑

Publish避免重新订阅。如果您要删除Publish,则解决方案如下所示,并且可以正常工作:

var result2 = source.Buffer(
        source.Where(s => s.EndsWith("."))
    )
    .Select(l => l.Aggregate((x, y) => x + y));

但是,result2将被两次订阅source,这可能是漏洞的来源,尤其是在source实施得不好或行为可观察的情况下。因此,当您两次订阅一个可观察对象时,最好使用Publish,它实际上是将消息从一个订阅“转发”到多个订阅。