MemoryStream等到有东西要读

时间:2014-12-03 08:15:31

标签: c# asynchronous stream

这是一个非常简单的问题,但我似乎无法在不与某人交谈的情况下解决这个问题。

我需要像MemoryStream这样的Stream,它会在读取时异步阻塞,直到有东西要读取或超时为止。

更新 好。我已经放弃并自己编写了Wrapper类,但EndRead总是返回0.请查看下面的代码。 (不要提供面向任务的解决方案。)

    public class BlockingMemoryStream : MemoryStream
    {
        ManualResetEventSlim isReadReady = new ManualResetEventSlim(false);

        public override void Write(byte[] buffer, int offset, int count)
        {
            base.Write(buffer, offset, count);
            //base.Position = offset; //I do not know if I need this!!!!
            isReadReady.Set();
        }

        public override IAsyncResult BeginRead(byte[] buffer, int offset, int count, AsyncCallback callback, object state)
        {
            IAsyncResult result = base.BeginRead(buffer, offset, count, callback, state);
            return result;
        }

        public override int EndRead(IAsyncResult asyncResult)
        {
            isReadReady.Wait(/*600000*/);
            int aa = base.EndRead(asyncResult);
            return aa;
        }
    }

2 个答案:

答案 0 :(得分:0)

尝试这样的事情,这样做只是循环并等待直到有对象被阅读。

    private static readonly MemoryStream _reader;
    private static object _data;

    static Program()
    {
        _reader = new MemoryStream();
    }

    private static void Main(string[] args)
    {
        Task.Run(async delegate()
        {
            while (true)
            {
                if (_data == null)
                    await Task.Delay(1000); // so the cpu can have rest
                                            // you can lower the value of this
                else
                {
                    // read here
                    await Task.Delay(1000);
                }
            }
        });
    }

答案 1 :(得分:0)

如果我理解正确,你想要一个你写的流,另一个线程从中读取。你可以自己动手,即:

public sealed class MyStream : Stream
{
    private readonly MemoryStream underlyingStream = new MemoryStream();
    private readonly AutoResetEvent waitHandle = new AutoResetEvent(false);

    public int Timeout { get; set; }

    public MyStream()
    {
        Timeout = 5000;
    }

    public override void Write(byte[] buffer, int offset, int count)
    {
        // Write to the stream and notify any waiting threads
        underlyingStream.Write(buffer, offset, count);
        waitHandle.Set();
    }

    public override int Read(byte[] buffer, int offset, int count)
    {
        int bytes;
        while ((bytes = underlyingStream.Read(buffer, offset, count)) == 0)
        {
            // 0 bytes read (end of stream), wait Timeout ms for someone to write
            if (!waitHandle.WaitOne(Timeout))
            {
                throw new TimeoutException();
            }
        }

        return bytes;
    }

    // TODO other mandatory methods
}

我在没有测试的情况下编写了上面的示例,并且Stream的实现不完整,它只是显示了解决方案的可能方向。如果多个线程Read,则可能需要多个Timeout才能完成。

如果你不喜欢摆弄等待句柄,你也可以在TCP环回上使用套接字并使用NetworkStream