Search code examples
c#memorydispose

Satisfying Code Analysing disposal rule with MemoryStream and CryptoStream


I have issues satisfying a code analysis rule for disposing a MemoryStream object.

This is my code right now:

byte[] bytes;
MemoryStream stream = new MemoryStream();

using (CryptoStream cs = new CryptoStream(stream, transform, CryptoStreamMode.Write))
{
    cs.Write(buffer, 0, buffer.Length);
}

bytes = stream.ToArray();
stream.Close();

return bytes;

This results in a warnings that the stream may be disposed twice, or may not be disposed (one warning for each).

I have also tried wrapping it into a using(MemoryStream stream = new MemoryStream()) block. This results in the former warning.

And finally, removing the calls to Close() or Dispose() results in the latter warning.

Is there a way to satisfy both conditions? I assume the problem is an exception path that may close it, but I am not very familiar with how these classes work.


Solution

  • I personally tend to suppress that rule in my source code if it fires because most objects do not have a problem being disposed twice. But if you want to satisfy the Rule without suppressing you need to do this:

            byte[] bytes = new byte[1024];
            byte[] buffer = new byte[1024];
            ICryptoTransform transform = null;
    
            MemoryStream stream = null;
    
            try
            {
                stream = new MemoryStream();
                MemoryStream tempStream = stream
    
                using (CryptoStream cs = new CryptoStream(stream, transform, CryptoStreamMode.Write))
                {
                    // set stream to null immediately so it doesn't get disposed by finally
                    stream = null;
    
                    cs.Write(buffer, 0, buffer.Length);
                    bytes = tempStream.ToArray();
                }
            }
            finally
            {
                if (stream != null)
                {
                    stream.Dispose();
                }
            }
    
            return bytes;