我有一个可以同时读写的流。 MSDN文档说我应该只在到达流末尾时从Read(buffer, offset, count)
方法返回零。
由于读取和写入是异步的,因此如果内部缓冲区为空,则读取需要等到另一次写入发生。
我正在努力解决写作方法如何表明所有内容都已被写入的问题。我能想到的最好的方法是Dispose()
(或Close()
)方法表示写作结束,但感觉非常错误。
我的流类实现为:
public class ContinuousStream : Stream
{
private readonly IProducerConsumerCollection<byte> _buffer;
public ContinuousStream() => _buffer = new ConcurrentQueue<byte>();
public override int Read(byte[] buffer, int offset, int count)
{
var maxByteCount = offset + count > buffer.Length ? buffer.Length : count;
var actualBytesRead = 0;
for (var i = offset; i < maxByteCount && _buffer.TryTake(out var b); i++)
{
buffer[i] = b;
actualBytesRead++;
}
return actualBytesRead;
}
public override void Write(byte[] buffer, int offset, int count)
{
var maxByteCount = offset + count > buffer.Length ? buffer.Length : count;
for (var i = offset; i < maxByteCount; i++)
{
_buffer.TryAdd(buffer[i]);
}
}
}
澄清
读写同时发生。阅读不应该等到一切都被缓冲后再运行。我怎么能向这个流发出信号,说明将要发生的所有文字都发生了?
答案 0 :(得分:0)
实际上,我不太明白为什么你需要流式传输,并且不能单独使用IProducerConsumerCollection 。其中许多参数毫无意义。只需使用TryTake&amp; TryAdd而不是Read&amp;写在第一位。
但您可以使用 AutoResetEvent :
public class ContinuousStream : Stream
{
private readonly AutoResetEvent _are = new AutoResetEvent(false);
private readonly IProducerConsumerCollection<byte> _buffer = new ConcurrentQueue<byte>();
public override int Read(byte[] buffer, int offset, int count)
{
_are.WaitOne();
var maxByteCount = offset + count > buffer.Length ? buffer.Length : count;
var actualBytesRead = 0;
for (var i = offset; i < maxByteCount && _buffer.TryTake(out var b); i++)
{
buffer[i] = b;
actualBytesRead++;
}
return actualBytesRead;
}
public override void Write(byte[] buffer, int offset, int count)
{
var maxByteCount = offset + count > buffer.Length ? buffer.Length : count;
for (var i = offset; i < maxByteCount; i++)
{
_buffer.TryAdd(buffer[i]);
_are.Set();
}
}
}