Question

I'm currently using two objects as follows:

using (var ms = new MemoryStream())
using (var bw = new BinaryWriter(ms))
{
    // work with ms and bw, both referenced here
}

It works "fine" and is in fact an answer here too. However, when I run VS2012's code analysis tool, I get a warning like:

CA2202  Do not dispose objects multiple times   
Object 'ms' can be disposed more than once in method '<my method name>'. 
To avoid generating a System.ObjectDisposedException you should not 
call Dispose more than one time on an object.

This leads me to believe there might an alternative way to handle this situation, but I don't know what it is.

Does anyone know what is the 'proper' way to use two objects within a single using block in a warning-free manner?

Was it helpful?

Solution

The BinaryWriter class is written such that it will dispose the underlying stream that you pass to it when you dispose the BinaryWriter unless you use the optional constructor parameter to tell it not to. Since the binary writer is disposing the underlying memory stream and you are also disposing of it in the using block it is being disposed of twice.

Now, this isn't really an issue for most classes, as they should be (and memory stream is) written to work just fine if disposed twice, as long as you don't use it after it's dispose (you're not) so you can safely ignore the warning. If you want the warning to go away you can just take the memory stream out of the using since it's already being disposed.

OTHER TIPS

If you don't need the object reference to MemoryStream this would work fine

using (var bw = new BinaryWriter(new MemoryStream()))
{
    var memStream = bw.BaseStream as MemoryStream;
}

Otherwise go for the multiple using. Especially in cases where you are using .NET framework objects, since they are implemented with correct dispose pattern.

A double using statement can cause trouble when the object that could have a second dispose call does not implement the dispose pattern correctly.

PS: do you get the same warning this way:

using (var memStream = new MemoryStream())
{
    using (var bw = new BinaryWriter(memStream))
    {
        // work with ms and bw
    }
}

You assumption that this is a single using block is incorrect. The code in your example is syntactic sugar for a nested using block like this:

using (var ms = new MemoryStream())
{
   using (var bw = new BinaryWriter(ms)) 
   {
    // work with ms and bw, both referenced here
   }
}

There is no single way to right this down correctly and avoid the warning. In cases where the inner resource wraps the outer resource and they both go out of scope together, you need to consult the documentation: if the contract states that the inner resource's dispose methods invoked the dispose of the wrapped object, you simply do not need to put the outer resource in a using block.

That being said, there will probably be no mention of such details in most docs. You can check the behavior by yourself (by inheriting and observing side effects) but than you must be careful since in the first place it was not documented, this behavior may change in future releases.

So if you are very worried about it, you can leave the double using block (just in case), suppress the warning and put the whole block in a try{} catch (ObjectDisposedException e) {} to safe gourd yourself completely.

Sounds paranoid? depends on what library you are working with :-)

I think you shouldn't use "using( ... ){}" for:

using (var ms = new MemoryStream())

because the OS managment memory and "dispose" it!

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top