protected sealed override void Dispose(bool disposing) { if (_strategy.IsClosed) { return; } try { Flush(); } catch (Exception e) when(!disposing && FileStreamHelpers.IsIoRelatedException(e)) { // On finalization, ignore failures from trying to flush the write buffer, // e.g. if this stream is wrapping a pipe and the pipe is now broken. } finally { // Don't set the buffer to null, to avoid a NullReferenceException // when users have a race condition in their code (i.e. they call // FileStream.Close when calling another method on FileStream like Read). // There is no need to call base.Dispose as it's empty _writePos = 0; _strategy.DisposeInternal(disposing); } }
/// <summary>Releases the unmanaged resources used by the stream.</summary> /// <param name="disposing">true to release both managed and unmanaged resources; false to release only unmanaged resources.</param> protected override void Dispose(bool disposing) { try { if (_fileHandle != null && !_fileHandle.IsClosed) { // Flush any remaining data in the file try { FlushWriteBuffer(); } catch (Exception e) when(!disposing && FileStreamHelpers.IsIoRelatedException(e)) { // On finalization, ignore failures from trying to flush the write buffer, // e.g. if this stream is wrapping a pipe and the pipe is now broken. } // If DeleteOnClose was requested when constructed, delete the file now. // (Unix doesn't directly support DeleteOnClose, so we mimic it here.) if (_path != null && (_options & FileOptions.DeleteOnClose) != 0) { // Since we still have the file open, this will end up deleting // it (assuming we're the only link to it) once it's closed, but the // name will be removed immediately. Interop.Sys.Unlink(_path); // ignore errors; it's valid that the path may no longer exist } // Closing the file handle can fail, e.g. due to out of disk space // Throw these errors as exceptions when disposing if (_fileHandle != null && !_fileHandle.IsClosed && disposing) { SafeFileHandle.t_lastCloseErrorInfo = null; _fileHandle.Dispose(); if (SafeFileHandle.t_lastCloseErrorInfo != null) { throw Interop.GetExceptionForIoErrno(SafeFileHandle.t_lastCloseErrorInfo.GetValueOrDefault(), _path, isDirectory: false); } } } } finally { if (_fileHandle != null && !_fileHandle.IsClosed) { _fileHandle.Dispose(); } base.Dispose(disposing); } }
/// <summary>Releases the unmanaged resources used by the stream.</summary> /// <param name="disposing">true to release both managed and unmanaged resources; false to release only unmanaged resources.</param> protected override void Dispose(bool disposing) { try { if (_fileHandle != null && !_fileHandle.IsClosed) { // Flush any remaining data in the file try { FlushWriteBuffer(); } catch (Exception e) when(!disposing && FileStreamHelpers.IsIoRelatedException(e)) { // On finalization, ignore failures from trying to flush the write buffer, // e.g. if this stream is wrapping a pipe and the pipe is now broken. } // Closing the file handle can fail, e.g. due to out of disk space // Throw these errors as exceptions when disposing if (_fileHandle != null && !_fileHandle.IsClosed && disposing) { SafeFileHandle.t_lastCloseErrorInfo = null; _fileHandle.Dispose(); if (SafeFileHandle.t_lastCloseErrorInfo != null) { throw Interop.GetExceptionForIoErrno(SafeFileHandle.t_lastCloseErrorInfo.GetValueOrDefault(), _fileHandle.Path, isDirectory: false); } } } } finally { if (_fileHandle != null && !_fileHandle.IsClosed) { _fileHandle.Dispose(); } base.Dispose(disposing); } }