且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

MemoryStream的一个线程写它,另一个读

更新时间:2023-11-22 13:59:28

您不能使用流从2寻求功能线程同时由于甲流状态十足。例如一个的NetworkStream有2个通道,一个用于读出和一个用于写,因此不能支持查找。

You can't use a Stream with seeking capabilities from 2 threads simultaneous since a Stream is state full. e.g. A NetworkStream has 2 channels, one for reading and one for writing and therefore can't support seeking.

如果你需要寻找功能,你需要创建2个数据流,一个用于读取,一个用于写入分别。否则,你可以简单地创建一个新的流类型,它允许读取和采取底层流独占访问从底层内存流写入并恢复其写入/读取的位置。这方面的一个原始的例子是:

If you need seeking capabilities, you need to create 2 streams, one for reading and one for writing respectively. Else you can simply create a new Stream type which allows reading and writing from a underlying memory stream by taking exclusive access to the underlying stream and restore its write/read position. A primitive example of that would be:

class ProducerConsumerStream : Stream
{
    private readonly MemoryStream innerStream;
    private long readPosition;
    private long writePosition;

    public ProducerConsumerStream()
    {
        innerStream = new MemoryStream();
    }

    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()
    {
        lock (innerStream)
        {
            innerStream.Flush();
        }
    }

    public override long Length
    {
        get 
        {
            lock (innerStream)
            {
                return innerStream.Length;
            }
        }
    }

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

    public override int Read(byte[] buffer, int offset, int count)
    {
        lock (innerStream)
        {
            innerStream.Position = readPosition;
            int red = innerStream.Read(buffer, offset, count);
            readPosition = innerStream.Position;

            return red;
        }
    }

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

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

    public override void Write(byte[] buffer, int offset, int count)
    {
        lock (innerStream)
        {
            innerStream.Position = writePosition;
            innerStream.Write(buffer, offset, count);
            writePosition = innerStream.Position;
        }
    }
}