tags:

views:

89

answers:

3

Typically I declare streams inside of a using statement to ensure that the stream is properly disposed when I am done with it, and so that I don't mistakenly call it when I'm outside the using block.

Some examples here: MSDN using Statement Reference

How does one use a using statement with an array of streams? Would it be equivalent to declare the array outside of a try/catch/finally block and call each stream's dispose method in the finally block?

Lastly, how does one test that the streams have been properly disposed?

+3  A: 

You have to do what using does without using using.

This means looping through the array and calling Dispose on each instance ( after casting explicitly to IDisposable, if needed). Do that loop in the finally block.

Lastly, you don't test for them being properly disposed. Once you call Dispose, you should just null them out, since you can't use them anymore.

Steven Sudit
+3  A: 

I would create a new object that holds the Streams in it. Something like this (not totally fleshed out):

class StreamHolder : IDisposable
{
  List<Stream> Streams {get;}

  public void  Dispose()
  {
      Streams.ForEach(x=>x.Dispose()):
  }
}

This way you can put the container object in the using statment, it will will handle the stream disposal for you. Your other option is the handle it in the Finally block, but if I were going to do this in more than one place, I would like to encapsulate it, so I don't accidentally forget to dispose of all the streams when I am done.

Kevin
This is ok, but it's much too specific. There's no reason not to make a generic EnumerableDisposer that is initialized with a IEnumerable. At that point, you would want to change the anon method so that it casts to IDisposable with an `as` and calls Dispose if not null. I've done precisely this in the past, and it works well.
Steven Sudit
That is a good point.
Kevin
Thanks all. Definitely need to check for the nullity of the streams, but this is more along the lines of the solution I was looking for.
scott
+2  A: 

The using () statement is a pattern for disposal intended to re-inforce good habits, but it is not required. There are plenty of situations where you need to store objects outside the lifetime of a scoped function.

While I think you should probably architect in a way where you can use the using() statement, the essential thing is that in some encopassing finally block, you dispose each of the streams.

To answer the last question, it does not appear that the Stream class has any method or property to determine if it has been closed/disposed, however if the IDisposable pattern is implemented correctly, you can call Close/Dispose again if you need to be sure.

David
You're right that additional calls to Dispose should be harmless, but there's no reason not to null the reference after the first call, since calling any other method is likely to raise an exception anyhow. Anyhow, +1 for suggesting that he change it to allow a `using`. I've done this before, using a generic Disposer object that is initialized on an IEnumerable and, in its own Dispose, casts each element to IDisposable so that (on success) it can call its Dispose.
Steven Sudit