ispiro
ispiro

Reputation: 27683

Disposing CryptoStream vs disposing underlying Stream?

I have a CryptoStream with an underlying Stream. I can't use a using block in order to dispose the CryptoStream because that also disposes the underlying Stream which I need to leave open. The solution seems to be simply to ignore the CryptoStream and just dispose of the Stream when needed. But perhaps it is important to keep a reference to the CryptoStream and dispose of it to prevent some resources leak?

Additionally, even if I don't dispose the CryptoStream might the GC dispose of it if it goes out of scope and then also dispose the underlying Stream, (which will be too early because I still need the Stream)?

Upvotes: 3

Views: 1009

Answers (1)

Yoh Deadfall
Yoh Deadfall

Reputation: 2781

From CryptoStream.cs (ln 695):

    protected override void Dispose(bool disposing) {
        try {
            if (disposing) {
                if (!_finalBlockTransformed) {
                    FlushFinalBlock();
                }
                _stream.Close();
            }                
        }
        finally {
            try {
                // Ensure we don't try to transform the final block again if we get disposed twice
                // since it's null after this
                _finalBlockTransformed = true;
                 // we need to clear all the internal buffers
                 if (_InputBuffer != null)
                     Array.Clear(_InputBuffer, 0, _InputBuffer.Length);
                 if (_OutputBuffer != null)
                     Array.Clear(_OutputBuffer, 0, _OutputBuffer.Length);

                 _InputBuffer = null;
                 _OutputBuffer = null;
                 _canRead = false;
                 _canWrite = false;
            }
            finally {
                 base.Dispose(disposing);
            }
        }
    }

As you can see you should call the FlushFinalBlock method which is public if you don't want to dispose a CryptoStream. This method clears the input and the output buffers so no sensitive information is stored in the used CryptoStream.

Might the GC close the underlying Stream? Nope. To do that the Dispose method must be called with true as its argument value, but this is done only in the Stream.Close method (called from Stream.Dispose). Even if CryptoStream would implement a finalizer it isn't a good practice to call Dispose on referenced objects when executing Finalize. Finalizers should be used only to free unmanaged resources.

Upvotes: 1

Related Questions