MemoryStream.Close() or MemoryStream.Dispose()
Which one do I call?
Is it necessary to call both?
Will the other throw an exception if I have already called one of them?
Close()
and Dispose()
, when called on a MemoryStream
, only serve to do two things:
- Mark the object disposed so that future accidental usage of the object will throw an exception.
- Possibly1 release references to managed objects, which can make the GC's job a bit easier depending on the GC implementation. (On today's GC algorithms it makes no real difference, so this is a point for an academic discussion and has no significant real-world impact.)
MemoryStream
does not have any unmanaged resources to dispose, so you don't technically have to dispose of it. The effect of not disposing a MemoryStream
is roughly the same thing as dropping a reference to a byte[]
-- the GC will clean both up the same way.
Which one do I call? Is it necessary to call both?
The Dispose()
method of streams delegate directly to the Close()
method2, so both do exactly the same thing.
Will the other throw an exception if I have already called one of them?
The documentation for IDisposable.Dispose()
specifically states it is safe to call Dispose()
multiple times, on any object3. (If that is not true for a particular class then that class implements the IDisposable
interface in a way that violates its contract, and this would be a bug.)
All that to say: it really doesn't make a huge difference whether you dispose a MemoryStream
or not. The only real reason it has Close
/Dispose
methods is because it inherits from Stream
, which requires those methods as part of its contract to support streams that do have unmanaged resources (such as file or socket descriptors).
1Mono's implementation does not release the byte[]
reference. I don't know if the Microsoft implementation does.
2"This method calls Close, which then calls Stream.Dispose(Boolean)."
3"If an object's Dispose method is called more than once, the object must ignore all calls after the first one."
None of the above. You needn't call either Close
or Dispose
.
MemoryStream
doesn't hold any unmanaged resources, so the only resource to be reclaimed is memory. The memory will be reclaimed during garbage collection with the rest of the MemoryStream
object when your code no longer references the MemoryStream
.
If you have a long-lived reference to the MemoryStream
, you can set that reference to null to allow the MemoryStream
to be garbage collected. Close
and Dispose
free neither the steam buffer nor the MemoryStream
object proper.
Since neither Stream
nor MemoryStream
have a finalizer, there is no need to call Close
or Dispose
to cause GC.SuppressFinalize
to be called to optimize garbage collection. There is no finalizer to suppress.
The docs for MemoryStream put it this way:
This type implements the
IDisposable
interface, but does not actually have any resources to dispose. This means that disposing it by directly callingDispose()
or by using a language construct such asusing
(in C#) orUsing
(in Visual Basic) is not necessary.
You can use the using
block for this. It will automatically call Dispose
when it goes outside of its scope.
Example:
using (MemoryStream ms = new MemoryStream())
{
// Do something with ms..
}
// ms is disposed here
Hope this helped.
Use using
block so that your object is disposed if its implements IDisposable
interface
Which one do I call?
Any of them.
Is it necessary to call both?
No, either one is sufficient.
Will the other throw an exception if I have already called one of them?
No, disposable pattern declares that subsequent calls to Dispose don't cause negative effects.