[英]How can I await that everything is done in a Rx observable sequence after unsubscribe?
[英]Learning Rx: How can I parse an observable sequence of characters into an observable sequence of strings?
這可能非常簡單,但我在Rx的學習曲線底部。 我花了幾個小時閱讀文章,觀看視頻和編寫代碼,但我似乎對一些似乎應該非常簡單的事情有一些心理障礙。
我正在從串口收集數據。 我使用Observable.FromEventPattern
捕獲SerialDataReceived
事件並將其轉換為可觀察的字符序列。 到現在為止還挺好。
現在,我想基於分隔符來解析該字符序列。 沒有涉及新行,但每個“數據包”數據都由前導碼和終結符包圍,兩個單個字符。 為了論證,我們可以說它們是大括號{
和}
。
所以,如果我得到的字符序列j
u
n
k
{
H
e
l
l
o
}
j
u
n
k
在我的字符序列,那么我想發出任何Hello
或{Hello}
我的字符串序列。
我可能錯過了一些簡單的東西,但我甚至無法弄清楚如何處理這個問題。 有什么建議嗎?
使用Publish
和Buffer
可以輕松完成此操作:
var source = "junk{Hello}junk{World}junk".ToObservable();
var messages = source
.Publish(o =>
{
return o.Buffer(
o.Where(c => c == '{'),
_ => o.Where(c => c == '}'));
})
.Select(buffer => new string(buffer.ToArray()));
messages.Subscribe(x => Console.WriteLine(x));
Console.ReadLine();
這個輸出是:
{Hello}
{World}
我們的想法是,您可以在調用Buffer
使用以下打開和關閉選擇器。 使用Publish
是為了確保所有三個Buffer
,開放選擇器和結束選擇器共享相同的訂閱。
source: junk{Hello}junk{World}junk|
opening: ----{----------{----------|
closing: ------}|
closing: ------}|
使用“ 掃描”將您的遠程接收值聚合到聚合字符串中( TAccumulate
是一個string
),並在每次獲得結束括號時將該字符串重置為""
。 (我將把實現聚合功能的工作留給你)。 這會產生類似的觀察
j
ju
jun
junk
junk{
junk{h
junk{hi
junk{hi}
j
ju
...
然后你可以使用Where只發出結尾的那些}
然后最后使用Select來擺脫junk
。
所以完整,應該是
IObservable<string> packetReceived =
serialPort.CharReceived
.Scan(YourAggregationFunction)
.Where(s => s.EndsWith("}"))
.Select(s => s.EverythingAfter("{"));
(我將EverythingAfter
留給你實施)。
只是注意,當您正在嘗試聚合函數時,使用string
的IEnumerable
接口來測試它可能更容易,即
foreach (s in "junk{hi}hunk{ji}blah".Scan(YourAggregationFunction))
Console.WriteLine(s);
好的,這是一個完整的工作示例
static void Main(string[] args) {
var stuff = "junk{hi}junk{world}junk".ToObservable()
.Scan("", (agg, c) => agg.EndsWith("}") ? c.ToString() : agg + c)
.Where(s => s.EndsWith("}"))
.Select(s => s.Substring(s.IndexOf('{')));
foreach (var thing in stuff.ToEnumerable()) {
Console.WriteLine(thing);
}
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.