Call to MemoryStream.GetBuffer() succeeds even after MemoryStream.Close(); Why?

c#, dispose, garbage-collection, memorystream

Solution

- It doesn't need to. The buffer is managed memory, so normal garbage collection will deal with it, without needing to be included in the disposal.

- It's useful to be able to get the bytes of the memory stream, even after the stream has been closed (which may have happened automatically after the steam was passed to a method that writes something to a stream and then closes said stream). And for that to work, the object needs to hold onto the buffer along with a record of how much had been written to it.

In considering the second point, it actually makes more sense in a lot of cases to call `ToArray()` (which as said, requires the in-memory store that `GetBuffer()` returns to still be alive) after you've closed the stream, because having closed the stream guarantees that any further attempt to write to the stream will fail. Hence if you have a bug where you obtain the array too early, it will throw an exception rather than just give you incorrect data. (Obviously if you explicitly want to get the current array part-way through the stream operations, that's another matter). It also guarantees that all streams are fully flushed rather than having part of their data in a temporary buffer (`MemoryStream` isn't buffered because `MemoryStream` essentially is a buffer, but you may have been using it with chained streams or writers that had their own separate buffer).

Problem

I have found the following construct in some open-source code: ``` var mstream = new MemoryStream(); // ... write some data to mstream mstream.Close(); byte[] b = mstream.GetBuffer(); ``` I thought this code would have "unexpected" behavior and maybe throw an exception, since the call to `Close` should effectively be a call to `Dispose` according to the MSDN documentation. However, as far as I have been able to tell from experimenting, the call to `GetBuffer()` always succeeds and returns a valid result, even if I `Thread.Sleep` for 20 seconds or enforce garbage collection via `GC.Collect()`. Should the call to `GetBuffer()` succeed even after `Close`/`Dispose`? In that case, why is not the underlying buffer released in the `MemoryStream` disposal?

Original source