Вопрос по c#, multithreading, stream, memorystream – MemoryStream имеет один поток записи в него и другой чтения

17

Вот как я пишу в поток, а затем читаю из него, используя 1 поток:

        System.IO.MemoryStream ms = new System.IO.MemoryStream();

        // write to it
        ms.Write(new byte[] { 1, 2, 3, 4, 5, 6, 7 }, 0, 7);

        // go to the begining
        ms.Seek(0, System.IO.SeekOrigin.Begin);

        // now read from it
        byte[] myBuffer = new byte[7];
        ms.Read(myBuffer, 0, 7);

Now I was wondering if it is possible to write to the memory-stream from one thread and read that stream from a separate thread.

Да, во многих местах, где они говорят об этом. Я просто буду признателен, если смогу увидеть очень простой пример того, как я смогу это сделать ... Tono Nam
Прочитай этоstackoverflow.com/questions/2825166/… Nikhil Agrawal

Ваш Ответ

1   ответ
15

з 2 потоков, так как поток заполнен. например NetworkStream имеет 2 канала, один для чтения и один для записи, и, следовательно, не может поддерживать поиск.

Если вам нужны возможности поиска, вам нужно создать 2 потока: один для чтения и один для записи соответственно. В противном случае вы можете просто создать новый тип потока, который позволяет чтение и запись из основного потока памяти, используя эксклюзивный доступ к базовому потоку и восстанавливая его позицию записи / чтения. Примитивным примером этого будет:

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;
        }
    }
}
Спасибо, теперь это имеет смысл! Tono Nam
Работает отлично, спасибо! Как мне реализовать метод поиска? я должен просто переместитьinnerStream.Position ? Tono Nam
Думаю об этом. Что вы хотите стремиться сделать? искать в канале чтения или искать в канале записи? или оба?
Похоже, хорошее решение.
Что произойдет, когда Потребитель выйдет за пределы Поставщика? Я полагаю, что это заставит Потребителя преждевременно получить конец потока.

Похожие вопросы