【发布时间】:2015-07-04 03:29:15
【问题描述】:
Rx 很棒,但有时很难找到优雅的方式来做某事。这个想法很简单。我收到带有 byte[] 的事件,这个数组可能包含一行、多行或一行的一部分。我想要的是找到一种方法来获得 Line 的 IObservable 所以IObservable<String>,其中序列的每个元素都是一行。
几个小时后,我发现的最接近的解决方案非常难看,而且当然不起作用,因为 scan 在每个字符上触发 OnNext :
//Intermediate subject use to transform byte[] into char
var outputStream = new Subject<char>();
_reactiveSubcription = outputStream
//Scan doesn't work it trigger OnNext on every char
//Aggregate doesn't work neither as it doesn't return intermediate result
.Scan(new StringBuilder(), (builder, c) => c == '\r' ? new StringBuilder() : builder.Append((char)c))
.Subscribe(this);
Observable.FromEventPattern<ShellDataEventArgs>(shell, "DataReceived")
//Data is a byte[]
.Select(_ => _.EventArgs.Data)
.Subscribe(array => array.ToObservable()
//Convert into char
.ForEach(c => outputStream.OnNext((char)c)));
注意:_reactiveSubcription 应该是IObservable<String>。
在不考虑字符编码问题的情况下,我缺少什么来完成这项工作?
【问题讨论】:
-
你在一个优雅的块中尝试做的事情在我的真实世界站中从未奏效。您如何知道 byte[] 已全部接收或它的结束字节在哪里?即,一条 2K 的消息是否会在一行中间的两个不同事件中以两个 1K 的块到达。我总是必须将字节弹出到理论上的无限队列中,并在这个其他构建的数组中查找我的 NewLine 或 CrLf,然后在 NewLines 和 CrLf 字符出现时将各个 Lines 拉出。如果没有 NewLine 或 CrLf 出现在我的 MaxLineSize 值中,我必须放置安全代码以清除构建的数组。
标签: c# system.reactive