Click here to Skip to main content
15,886,919 members
Please Sign up or sign in to vote.
2.00/5 (1 vote)
See more:
C#

I can't find any information on the Internet about this scenario, so I'm hoping someone can enlighten me.

I have an app with a picturebox control that is used to display animated GIF images. I load an image into the picturebox using an OpenFileDialog and then I convert the image to a Base64 string using a MemoryStream and store that string into a list. When loading an image from the list, the image is converted from Base64 string back into an image using a MemoryStream and loaded into the picturebox.

Question: In order for animated GIFs to animate in the picturebox, I must leave the MemoryStream open. Otherwise the animated GIF won't animate. But every time I load a new image into the picturebox, I create a new instance of MemoryStream. By loading images this way without closing their associated MemoryStreams, I assume that my app will leave a bunch of leftover MemoryStreams from all the images that are no longer displayed in the picturebox. I want to keep my app's memory usage low by closing any MemoryStreams that are no longer needed, but I can't close a MemoryStream inside the function where it is created without affecting the current image's animation.
Posted
Updated 12-Feb-15 12:27pm
v2

Yes, you need to close it. The regular way to use it is to call IDisposeable.Dispose(); this interface is implemented by all stream and reader/writer types.

Moreover, you should never miss this call. You have to make sure to call IDisposeable.Dispose() for all objects of types implementing this interface, no matter what, before it becomes unreachable. If you fail to to do, the unreachable object will become garbage-collected, but side effect of disposal will be missed; it can lead to very unpleasant problems, such as: unmanaged memory leak (or leak of other resources), unclosed file handles (the files will remain inaccessible during lifetime of your applications), and other bad things.

Please see:
http://en.wikipedia.org/wiki/Garbage_collection_%28computer_science%29[^],
https://msdn.microsoft.com/en-us/library/system.idisposable%28v=vs.110%29.aspx[^].

For all types you have to work with, check up if they implement this interface or not.

—SA
 
Share this answer
 
v2
Comments
dudefromthebronx 12-Feb-15 19:57pm    
In other words, I could write the code for deleting the image from the picturebox like this:

private void btnClearAnswerResponseImage_Click(object sender, EventArgs e)
{
if (pbTitlePageImage.Image != null)
pbTitlePageImage.Image.Dispose();
pbAnswerResponseImage.Image = null;
}

And this code would not only delete the image from the picturebox, but also delete its memory stream from the computer's memory, correct?
Sergey Alexandrovich Kryukov 12-Feb-15 22:42pm    
That's right, but not exactly. You don't delete anything from memory explicitly. There can be managed and unmanaged memory. Unmanaged memory, handles is supposed to be reclaimed by IDisposable.Dispose(), which can also be used for any clean-up operations. Managed memory is reclaimed by GC by its own schedule, and only after the system calculates that your process cannot access the object by reference anymore. This moment of time is unpredictable (in particular, you cannot rely on the time of the call to the destructor; that's why destructors are pretty rarely used). I referenced the article on GC, please see.

Also, strictly speaking, you should dispose the image stream not only when you replace the image, but in all cases when it is no longer needed. Apparently, you eventually close the application and should do it. For this, the pattern using Dispose(bool disposing) is used for cascade disposing of all things owned, for example, by the application.

—SA
Thank you, Sergey, for your insight. Now I know what to do in situations like this.
 
Share this answer
 

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900