tags:

views:

42

answers:

2

I have some code that does

MemoryStream ms = new MemoryStream();
...
return Image.FromStream(ms);

It fails in very eclectic ways since the Image object does not hold a ref to the stream, so it can get disposed if the GC kicks in which results in GDI+ errors.

How do I work around this (without saving the stream to disk, or altering my method sigs) ?

+1  A: 

There isn't a way to do it without changing your code somewhat. The Remarks section for the documentation for the static FromStream method on the Image class states:

You must keep the stream open for the lifetime of the Image.

That being said, you have to make sure that while the Image is accessing the Stream, the stream is open. It would also appear (looking through Reflector) that the FromImage method doesn't actually cause the Image instance to hold onto a reference to the Stream the image was loaded from.

That being said, you to somehow link the image and the MemoryStream (or Stream) together so that it doesn't get GCed. If don't really retain "ownership" of the image (it is passed around), then I recommend that you create a data structure which will hold the reference to the Image and to the Stream and pass the two around in tandem.

casperOne
I don't get it. If the image requires the stream to be open, then it must hold a reference to it, right?
Isaac Cambron
@Issac Cambron: Yes, and that's fine, but it's referring to the Stream being open, not the reference being valid. To that end, if you are passing the Image around and don't have control over when it is closed (or maybe you are closing it yourself somewhere else when the Image still needs it). I'm updating the answer to reflect this.
casperOne
@Sam Saffron: If you clone the image, I would assume you have to still keep the stream around. The documentation for the Clone method isn't too explicit, saying it produces an "exact copy" which can be interpreted a number of different ways. I wouldn't dobut if the clone requires the original stream to be open as well.
casperOne
+1  A: 

This seems highly unlikely to me - it would cause a problem for almost any use of Image.FromStream.

It seems more likely to me that something's disposing of your MemoryStream, which it shouldn't.

Could you provide a short but complete program which demonstrates the problem? Forcing garbage collection should make it relatively easy to reproduce - you could even create your own class deriving from MemoryStream with a finalizer to show whether or not it really is being collected (well, finalized at least).

Jon Skeet
@Sam: `read` should always be greater than **0** if there's more data in the stream - but it can easily be less than `buffer.Length`, even if there's more data still in the stream afterwards.
Jon Skeet
yeah, it all turned out to be this: http://stackoverflow.com/questions/2340337/how-can-i-get-net-to-open-this-image
Sam Saffron