Is there a blocking StreamReader, TextReader or StringReader in .NET?

I want to run a background job that reads input from a TextReader and processes it in turn. I want the background task to be locked until the user types the text in the field and clicks the submit button. Is there any taste of TextReader that will block until the text is available and allow somehow to add more text to the original source?

I thought that StreamReader and StreamWriter pointing to the same MemoryStream might work, but that doesn't seem to be the case. StreamReader sees that the MemoryStream is empty at the beginning and never checks again.

I understand that it would be easier to write the ProcessLine () method and call it whenever the user clicks the submit button. However, I am trying to create a plug-in architecture, and I would like the plugins to look like old-fashioned console applications with an input stream and an output stream. I want the input plug to simply be blocked until the user clicks the submit button with some input text.

+3
source share
2 answers

It seems that the implementation of this does not exist - which is strange, since I agree that this will be a useful construct. But it should be easy to write. Something like this should work:

  public class BlockingStream: Stream
  {
    private readonly Stream _stream;

    public BlockingStream(Stream stream)
    {
      if(!stream.CanSeek)
        throw new ArgumentException("Stream must support seek", "stream");
      _stream = stream;
    }

    public override void Flush()
    {
      lock (_stream)
      {
        _stream.Flush();
        Monitor.Pulse(_stream);
      }
    }

    public override long Seek(long offset, SeekOrigin origin)
    {
      lock (_stream)
      {
        long res = _stream.Seek(offset, origin);
        Monitor.Pulse(_stream);
        return res;
      }
    }

    public override void SetLength(long value)
    {
      lock (_stream)
      {
        _stream.SetLength(value);
        Monitor.Pulse(_stream);
      }
    }

    public override int Read(byte[] buffer, int offset, int count)
    {
      lock (_stream)
      {
        do
        {
          int read = _stream.Read(buffer, offset, count);
          if (read > 0)
            return read;
          Monitor.Wait(_stream);
        } while (true);
      }
    }

    public override void Write(byte[] buffer, int offset, int count)
    {
      lock (_stream)
      {
        long currentPosition = _stream.Position;
        _stream.Position = _stream.Length;
        _stream.Write(buffer, offset, count);
        _stream.Position = currentPosition;
        Monitor.Pulse(_stream);
      }
    }

    public override bool CanRead
    {
      get
      {
        lock (_stream)
        {
          return _stream.CanRead;
        }
      }
    }

    public override bool CanSeek
    {
      get
      {
        lock (_stream)
        {
          return _stream.CanSeek;
        }
      }
    }

    public override bool CanWrite
    {
      get
      {
        lock (_stream)
        {
          return _stream.CanWrite;
        }
      }
    }

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

    public override long Position
    {
      get
      {
        lock (_stream)
        {
          return _stream.Position;
        }
      }
      set
      {
        lock (_stream)
        {
          _stream.Position = value;
          Monitor.Pulse(_stream);
        }
      }
    }
  }
+5
source

, , , Submit. . , . , , .

+5

Source: https://habr.com/ru/post/1698899/


All Articles