/// <inheritdoc /> protected override void Dispose(bool disposing) { base.Dispose(disposing); if (disposing) { using (StreamOperationToken op = StartNewOperation(StreamOperation.Dispose)) { BackgroundOperationSlot slot = op.WaitForBackgroundOperationSlot(); if (slot.Usability != StreamUsability.Broken) { FlushOrDiscardBufferAsync(slot).GetAwaiter().GetResult(); } if (m_ownsFile) { m_file.Close(); } if (slot.Usability == StreamUsability.Broken) { throw slot.ThrowExceptionForBrokenStream(); } } } // TODO: Consider FailFast for the !disposing (finalizer) case. internalBuffer.Dispose(); }
/// <summary> /// <see cref="Stream.Flush"/> /// </summary> public override void Flush() { using (StreamOperationToken op = StartNewOperation(StreamOperation.Flush)) { BackgroundOperationSlot slot = op.WaitForBackgroundOperationSlot(); if (slot.Usability == StreamUsability.Broken) { throw slot.ThrowExceptionForBrokenStream(); } // TODO: Shouldn't drop the read buffer unless seeking to a new position. FlushOrDiscardBufferAndResetPositionAsync(op, slot, m_position).GetAwaiter().GetResult(); } }
/// <summary> /// <see cref="Stream.Seek(long, SeekOrigin)"/> /// </summary> public override long Seek(long offset, SeekOrigin origin) { using (StreamOperationToken token = StartNewOperation(StreamOperation.Seek)) { BackgroundOperationSlot slot = token.WaitForBackgroundOperationSlot(); if (slot.Usability == StreamUsability.Broken) { throw slot.ThrowExceptionForBrokenStream(); } long offsetFromStart; switch (origin) { case SeekOrigin.Begin: Contract.Assume(offset >= 0, "Attempted to seek to a negative offset"); offsetFromStart = offset; break; case SeekOrigin.Current: Contract.Assume(m_position >= offset, "Attempted to seek (relative to current) to a negative offset"); offsetFromStart = m_position + offset; break; case SeekOrigin.End: throw new NotSupportedException("Seeking relative to stream end is not supported"); default: throw Contract.AssertFailure("Unknwon SeekOrigin"); } if (m_position != offsetFromStart) { FlushOrDiscardBufferAndResetPositionAsync(token, slot, offsetFromStart).GetAwaiter().GetResult(); } return(offsetFromStart); } }