简体   繁体   English

反应框架消除了Observable.Create中的while循环

[英]Reactive framework eliminate while loop in Observable.Create

I am working with an observable byte stream, coming off of the network, and I would like to take that up one layer of abstraction. 我正在处理从网络传来的可观察字节流,我希望将其用于一层抽象。 The format has two bytes that contain the length of the next message. 该格式有两个字节,其中包含下一条消息的长度。 I'd like to make this fit into the reactive framework pretty well. 我想很好地使其适应于反应式框架。 What I have so far feels not quite right, so I am wondering what tricks I may have missed to eliminate the while loop here. 到目前为止,我感觉还不太对,所以我想知道我可能错过了哪些技巧来消除while循环。

Here's the concept I have in mind: 这是我想到的概念:

public static IObservable<Stream> GetToplevelStreams(IObservable<byte> byteStreamArg) {
    return Observable.Create((IObserver<Stream>o)=>{
        bool done = false;
        var byteStream = byteStreamArg.Do(
            b => { }, (ex) => { done = true; }, () => { done = true; });
        while (!done)
        {
            var size = byteStream.Take(2).
                           Aggregate(0, (n, b) => (n << 8) + b).Single();
            var buf = byteStream.Skip(2).Take(size);
            var stream = new MemoryStream(buf.ToEnumerable().ToArray());
            if (!done)
            {
                o.OnNext(stream);
            }
        }
        return (() => {});
    });
}

An IObservable is a bit weird here - remember that you're returning a "Future List of Streams" - I'd actually just return a Stream , or perhaps an IObservable<byte[]> , where each array represents a message. IObservable在这里有点奇怪-记住您要返回“流的未来列表”-实际上我只是返回Stream ,或者可能是IObservable<byte[]> ,其中每个数组代表一条消息。 Or do even better, and return an IObservable<ParsedMessage> 甚至做得更好,并返回IObservable<ParsedMessage>

Also, your While loop makes this non-async and act strangely. 同样,您的While循环会使此动作与异步行为发生异常。 How about something more like this: 像这样的东西怎么样:

public static IObservable<System.IO.Stream> GetToplevelStreams(IObservable<byte> byteStream)
{
    return Observable.Create((IObserver<System.IO.Stream> o) =>
    {
        int? size1=null;
        int? size=null;
        var buf = new MemoryStream();
        var subscription = byteStream.Subscribe(v =>
        {
            if (!size1.HasValue)
            {
                size1 = ((int)v) << 8;
            }
            else if (!size.HasValue)
            {
                size = size1.Value + v;
            }
            else
            {
                buf.WriteByte(v);
            }
            if (size.HasValue && buf.Length == size)
            {
                buf.Position = 0;
                o.OnNext(buf);
                buf.SetLength(0);
                size1 = null;
                size = null;
            }

        }, (ex)=>o.OnError(ex), ()=>o.OnCompleted());
        return () => subscription.Dispose();
    });
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM