I've recently encountered an error "ObjectDisposedException: Cannot access a closed Stream"
[ObjectDisposedException: Cannot access a closed Stream.]
System.IO.MemoryStream.Write(Byte[] buffer, Int32 offset, Int32 count) +10184402
System.Security.Cryptography.CryptoStream.FlushFinalBlock() +114
System.Security.Cryptography.CryptoStream.Dispose(Boolean disposing) +48
when using code following the format:
using (var stream = new MemoryStream())
{
using (var hashStream = new CryptoStream(stream,
new SHA256Managed(), CryptoStreamMode.Write))
using (var writer = new TextWriter(hashStream))
{
writer.Write("something");
}
// ^-- Exception occurs on hashStream Dispose
// While naively I assumed that TextWriter.Dispose wouldn't touch the
// underlying stream(s).
return stream.ToArray();
}
So the exception is caused because the Dispose of the TextWriter Disposes the Stream (hashStream) that is wrapped. My questions are thus:
Does this convention applied (with default constructors/arguments) to all stream in .NET?
Is there canon discussing this resource usage pattern? For instance, can it be assumed that the CryptoStream would have closed the MemoryStream? I know the answer, and there are other questions specifically about this, but I would like it addressed in terms of a design guideline if there is such.
Where is such behavior documented?
I can't find "ownerships" discussed in the
TextWriter(stream)
orCryptoStream
constructors - surely I am just looking at the wrong location. (Update: apparently I fail at reading, as pointed out by itsme86 this is documented in the TextWriter constructor documentation.)What is the universal accepted method to write such code?
That is, the underlying stream needs to be read (at the end of all operations, and thus still open) while all the nested streams should be closed/flushed completely - a simple CryptoStream.Flush is not sufficient, for instance.