无缓存高效流(NoCacheStream)

场景:某个方法需要写入流,另一个方法需要将刚写入流的内容读取再处理,整个过程是一次性无需缓存的情况下,可以不使用MemoryStream,那个会占内存,同时由于MemoryStream容量的不固定,扩容的过程也会对性能产生影响。为了可以提供高效的流读写性能,设计一个无缓存流。

此流的写入和读取必须分为2个不同的线程,否则将无法正常工作,推荐写入使用后台线程,而读取使用当前线程,即直接当前线程使用该流对象(读取或返回)。

此流的写入是基于读取的,如果没有读取,写入将无限等待,直到有读取动作,获取读取方缓存,直接往读取方缓存数组中写入。

/// <summary>
/// Written in reading
/// </summary>
public class NoCacheStream : Stream
{
    private ManualResetEvent enablewrite = new ManualResetEvent(false);
    private AutoResetEvent enableread = new AutoResetEvent(false);
    private volatile byte[] innerbuffer;
    private int num, inneroffset, innercount;
    private bool isend;

    public override bool CanRead
    {
        get { return true; }
    }

    public override bool CanSeek
    {
        get { return false; }
    }

    public override bool CanWrite
    {
        get { return true; }
    }

    public override void Flush()
    {
        throw new NotImplementedException();
    }

    public override long Length
    {
        get { throw new NotImplementedException(); }
    }

    public override long Position
    {
        get
        {
            throw new NotImplementedException();
        }
        set
        {
            throw new NotImplementedException();
        }
    }

    public override int Read(byte[] buffer, int offset, int count)
    {
        if (isend)
            return 0;

        innerbuffer = buffer;
        inneroffset = offset;
        innercount = count;
        num = 0;
        enablewrite.Set(); // allow write
        enableread.WaitOne(); // wait to read
        return num;
    }

    public override long Seek(long offset, SeekOrigin origin)
    {
        throw new NotImplementedException();
    }

    public override void SetLength(long value)
    {
        throw new NotImplementedException();
    }

    public override void Write(byte[] buffer, int offset, int count)
    {
        if (isend)
            return;

        enablewrite.WaitOne();//wait read method signal

        while (count >= innercount)
        {
            Array.Copy(buffer, offset, innerbuffer, inneroffset, innercount);
            offset += innercount;
            count -= innercount;
            num += innercount;
            enablewrite.Reset();//block write
            enableread.Set();//allow read
            enablewrite.WaitOne();//wait to write
        }

        if (count > 0)
        {
            Array.Copy(buffer, offset, innerbuffer, inneroffset, count);
            inneroffset += count;
            innercount -= count;
            num += count;
        }
    }

    /// <summary>
    /// End of read-write
    /// </summary>
    public void End()
    {
        isend = true;
        enableread.Set();
    }
}

 

posted @ 2015-06-15 20:17  秦楼东  阅读(479)  评论(0编辑  收藏  举报