Existe um stream de memory que bloqueia como um stream de arquivos

Estou usando uma biblioteca que requer que eu forneça um object que implemente essa interface:

public interface IConsole { TextWriter StandardInput { get; } TextReader StandardOutput { get; } TextReader StandardError { get; } } 

Os leitores do object são então usados ​​pela biblioteca com:

 IConsole console = new MyConsole(); int readBytes = console.StandardOutput.Read(buffer, 0, buffer.Length); 

Normalmente, a class que implementa o IConsole possui o stream StandardOutput como proveniente de um processo externo. Nesse caso, o console.StandardOutput.Read chama o trabalho bloqueando até que alguns dados sejam gravados no stream StandardOutput.

O que estou tentando fazer é criar uma implementação de IConsole de teste que use MemoryStreams e echo seja o que for exibido no StandardInput de volta para o StandardInput. Eu tentei:

 MemoryStream echoOutStream = new MemoryStream(); StandardOutput = new StreamReader(echoOutStream); 

Mas o problema com isso é que o console.StandardOutput.Read retornará 0 em vez de bloquear até que haja alguns dados. Existe alguma maneira que eu possa obter um MemoryStream para bloquear se não houver dados disponíveis ou se houver algum stream de memory diferente que eu possa usar?

Inspirado por sua resposta, aqui está minha versão multi-thread, multi-write:

 public class EchoStream : MemoryStream { private readonly ManualResetEvent _DataReady = new ManualResetEvent(false); private readonly ConcurrentQueue _Buffers = new ConcurrentQueue(); public bool DataAvailable{get { return !_Buffers.IsEmpty; }} public override void Write(byte[] buffer, int offset, int count) { _Buffers.Enqueue(buffer); _DataReady.Set(); } public override int Read(byte[] buffer, int offset, int count) { _DataReady.WaitOne(); byte[] lBuffer; if (!_Buffers.TryDequeue(out lBuffer)) { _DataReady.Reset(); return -1; } if (!DataAvailable) _DataReady.Reset(); Array.Copy(lBuffer, buffer, lBuffer.Length); return lBuffer.Length; } } 

Com sua versão, você deve ler o stream após a gravação, sem que qualquer gravação consecutiva seja possível. Minha versão armazena em buffer qualquer buffer escrito em um ConcurrentQueue (é bastante simples alterá-lo para uma fila simples e bloqueá-lo)

No final, encontrei uma maneira fácil de fazer isso, herdando do MemoryStream e assumindo os methods Read e Write.

 public class EchoStream : MemoryStream { private ManualResetEvent m_dataReady = new ManualResetEvent(false); private byte[] m_buffer; private int m_offset; private int m_count; public override void Write(byte[] buffer, int offset, int count) { m_buffer = buffer; m_offset = offset; m_count = count; m_dataReady.Set(); } public override int Read(byte[] buffer, int offset, int count) { if (m_buffer == null) { // Block until the stream has some more data. m_dataReady.Reset(); m_dataReady.WaitOne(); } Buffer.BlockCopy(m_buffer, m_offset, buffer, offset, (count < m_count) ? count : m_count); m_buffer = null; return (count < m_count) ? count : m_count; } }