MemoryStream.Close() or MemoryStream.Dispose()

.net, c#, garbage-collection

Solution

`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).

1 Mono'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."

Problem

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?

Original source

Related problems