从流不断读书吗? [英] Continuously reading from a stream?

查看:134
本文介绍了从流不断读书吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个Stream对象,偶尔得到一些关于它的数据,但在未predictable区间。上出现的流消息是明确定义和申报的载荷的大小在预先(大小是包含在每个消息的前两个字节的16位整数)。

I have a Stream object that occasionally gets some data on it, but at unpredictable intervals. Messages that appear on the Stream are well-defined and declare the size of their payload in advance (the size is a 16-bit integer contained in the first two bytes of each message).

我想有检测时,流上有一些数据的StreamWatcher类。一旦这样做,我想事件得到提升,这样一个订阅StreamProcessor实例可以处理新的消息。

I'd like to have a StreamWatcher class which detects when the Stream has some data on it. Once it does, I'd like an event to be raised so that a subscribed StreamProcessor instance can process the new message.

可以这样用C#事件做而不直接使用线程?现在看来似乎应该是简单的,但我不能得到完全得到我的头周围以正确的方式来设计这一点。

Can this be done with C# events without using Threads directly? It seems like it should be straightforward, but I can't get quite get my head around the right way to design this.

推荐答案

当你说不能使用线程的直接的,我想你还是想通过异步使用它们的间接的呼叫,否则这将不会是非常有用的。

When you say not use threads directly, I assume you still want to use them indirectly via async calls, otherwise this wouldn't be very useful.

所有你需要做的是包裹的异步方法和结果存储在缓冲区中。首先,让我们定义规范的情况下,一部分:

All you need to do is wrap the async methods of the Stream and store the result in a buffer. First, let's define the event part of the spec:

public delegate void MessageAvailableEventHandler(object sender,
    MessageAvailableEventArgs e);

public class MessageAvailableEventArgs : EventArgs
{
    public MessageAvailableEventArgs(int messageSize) : base()
    {
        this.MessageSize = messageSize;
    }

    public int MessageSize { get; private set; }
}

现在,从流中读取一个16位的整数异步和报到时,它的准备:

Now, read one 16-bit integer from the stream asynchronously and report back when it's ready:

public class StreamWatcher
{
    private readonly Stream stream;

    private byte[] sizeBuffer = new byte[2];

    public StreamWatcher(Stream stream)
    {
        if (stream == null)
            throw new ArgumentNullException("stream");
        this.stream = stream;
        WatchNext();
    }

    protected void OnMessageAvailable(MessageAvailableEventArgs e)
    {
        var handler = MessageAvailable;
        if (handler != null)
            handler(this, e);
    }

    protected void WatchNext()
    {
        stream.BeginRead(sizeBuffer, 0, 2, new AsyncCallback(ReadCallback),
            null);
    }

    private void ReadCallback(IAsyncResult ar)
    {
        int bytesRead = stream.EndRead(ar);
        if (bytesRead != 2)
            throw new InvalidOperationException("Invalid message header.");
        int messageSize = sizeBuffer[1] << 8 + sizeBuffer[0];
        OnMessageAvailable(new MessageAvailableEventArgs(messageSize));
        WatchNext();
    }

    public event MessageAvailableEventHandler MessageAvailable;
}

我想这就是它。这假定任何类处理消息还先后获得了是prepared阅读,同步或异步,基于事件的消息大小。如果你想观察者类实际读取整个消息,那么你就必须增加一些code做到这一点。

I think that's about it. This assumes that whichever class is handling the message also has access to the Stream and is prepared to read it, synchronously or asynchronously, based on the message size in the event. If you want the watcher class to actually read the entire message then you'll have to add some more code to do that.

这篇关于从流不断读书吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆