[ACCEPTED]-Does Stream.Dispose always call Stream.Close (and Stream.Flush)-using
Can I just call MySW.Dispose() and skip 10 the Close even though it is provided?
Yes, that’s 9 what it’s for.
Are there any Stream implementations that 8 don't work as expected (Like CryptoStream)?
It 7 is safe to assume that if an object implements 6 IDisposable
, it will dispose of itself properly.
If 5 it doesn’t, then that would be a bug.
If 4 not, then is the following just bad code:
No, that 3 code is the recommended way of dealing with 2 objects that implement IDisposable
.
More excellent information 1 is in the accepted answer to Close and Dispose - which to call?
I used Reflector and found that System.IO.Stream.Dispose
looks like 1 this:
public void Dispose()
{
this.Close();
}
As Daniel Bruckner mentioned, Dispose and 8 Close are effectively the same thing.
However 7 Stream does NOT call Flush() when it is 6 disposed/closed. FileStream (and I assume 5 any other Stream with a caching mechanism) does 4 call Flush() when disposed.
If you are 3 extending Stream, or MemoryStream etc. you 2 will need to implement a call to Flush() when 1 disposed/closed if it is necessary.
All standard Streams (FileStream, CryptoStream) will 10 attempt to flush when closed/disposed. I 9 think you can rely on this for any Microsoft 8 stream implementations.
As a result, Close/Dispose 7 can throw an exception if the flush fails.
In 6 fact IIRC there was a bug in the .NET 1.0 5 implementation of FileStream in that it 4 would fail to release the file handle if 3 the flush throws an exception. This was 2 fixed in .NET 1.1 by adding a try/finally 1 block to the Dispose(boolean) method.
Both StreamWriter.Dispose() and Stream.Dispose() release 8 all resources held by the objects. Both 7 of them close the underlying stream.
The 6 source code of Stream.Dispose() (note that 5 this is implementation details so don't 4 rely on it):
public void Dispose()
{
this.Close();
}
StreamWriter.Dispose() (same 3 as with Stream.Dispose()):
protected override void Dispose(bool disposing)
{
try
{
// Not relevant things
}
finally
{
if (this.Closable && (this.stream != null))
{
try
{
if (disposing)
{
this.stream.Close();
}
}
finally
{
// Not relevant things
}
}
}
}
Still, I usually 2 implicitly close streams/streamwriters before 1 disposing them - I think it looks cleaner.
For objects that need to be manually closed, every 5 effort should be made to create the object 4 in a using block.
//Cannot access 'stream'
using (FileStream stream = File.Open ("c:\\test.bin"))
{
//Do work on 'stream'
} // 'stream' is closed and disposed of even if there is an exception escaping this block
// Cannot access 'stream'
In this way one can never 3 incorrectly access 'stream' out of the context 2 of the using clause and the file is always 1 closed.
I looked in the .net source for the Stream 2 class, it had the following which would 1 suggest that yes you can...
// Stream used to require that all cleanup logic went into Close(),
// which was thought up before we invented IDisposable. However, we
// need to follow the IDisposable pattern so that users can write
// sensible subclasses without needing to inspect all their base
// classes, and without worrying about version brittleness, from a
// base class switching to the Dispose pattern. We're moving
// Stream to the Dispose(bool) pattern - that's where all subclasses
// should put their cleanup starting in V2.
public virtual void Close()
{
Dispose(true);
GC.SuppressFinalize(this);
}
public void Dispose()
{
Close();
}
Stream.Close
is implemented by a call to Stream.Dispose
or vice versa 7 - so the methods are equivalent. Stream.Close
exists 6 just because closing a stream sounds more 5 natural than disposing a stream.
Besides 4 you should try to avoid explicit calls to 3 this methods and use the using
statement instead 2 in order to get correct exception handling 1 for free.
More Related questions
We use cookies to improve the performance of the site. By staying on our site, you agree to the terms of use of cookies.