public override int Read(byte[] buffer, int offset, int count) { lock (_lock) { if (_isReading) { throw new InvalidOperationException("Read operation already in progress"); } _isReading = true; } try { while (true) { lock (_lock) { if (_isDisposed) { throw new ObjectDisposedException(this.GetType().Name); } } var countBitten = _from.Bite(buffer, offset, count); if (countBitten == 0) { // no bytes right now. var gotSignal = _fromSignal.WaitOne(WAIT_MILLISECONDS); if (gotSignal) { var countBittenAfterWaiting = _from.Bite(buffer, offset, count); return(countBittenAfterWaiting); // we've got signal, so return wheither we have bitten or not. } } else { // got some bytes return(countBitten); } } } finally { lock (_lock) { _isReading = false; } } }
public override int Read(byte[] buffer, int offset, int count) { lock (_readLock) { if (_accumulator.IsEmpty) { // read all from inner stream var readFromInnerStreamBytesCount = _innerStream.Read(buffer, offset, count); this.ReadFromInnerStream?.Invoke(buffer, offset, readFromInnerStreamBytesCount); return(readFromInnerStreamBytesCount); } else { // first, bite from accumulator var bittenBytesCount = _accumulator.Bite(buffer, offset, count); var readFromInnerStreamBytesCount = 0; var remaining = count - bittenBytesCount; // second, read from inner stream if still need to. if (remaining > 0) { readFromInnerStreamBytesCount = _innerStream.Read(buffer, offset + bittenBytesCount, remaining); this.ReadFromInnerStream?.Invoke(buffer, offset + bittenBytesCount, readFromInnerStreamBytesCount); } var totalRead = bittenBytesCount + readFromInnerStreamBytesCount; return(totalRead); } } }