Hello. I have a picture box on a form. The imageLocation of the picture box is set to a url like for example "http://www.google.mu/imgres?imgurl=http://1.bp.blogspot.com/-w6AJJ5Xoulg/T3AymMKbFlI/AAAAAAAAACI/EslCtw42HHg/s1600/jpeg.jpg&imgrefurl=http://zainriasat786.blogspot.com/2012/03/discuss-impact-that-file-format.html&h=480&w=640&sz=36&tbnid=fkqhzaWg8cSK4M:&tbnh=90&tbnw=120&zoom=1&usg=__54xTPooPnJOFy8xQS0TJXOtV1d8=&docid=JkpXnRk64SCIzM&hl=en&sa=X&ei=LjxoUO_uEsXRrQf28oDYBw&sqi=2&ved=0CD0Q9QEwBA&dur=24". When the form closes, we can see that memory is not released. I have added code to dispose the picture box on form closing but when I open the form again, the form crashes.
Is .Dispose() the best way to prevent memory leaks?

Memory isn't release immediately (though it may be). The garbage collector runs when it thinks it should.

But yes, using Dispose is what you do on objects that maintain non-managed resources. If your form crashes when you try to open it again, that's a coding issue on your part :)

Inline Code Example HereHi Memorath, thanks for your reply.

My code to dipose the pictureboxes is as follows:

 public void DisposeImageControls(Control mainCntl)
        {
            foreach (Control cntl in mainCntl.Controls)
            {
                if (cntl.GetType() == typeof(PictureBox))
                {
                    if (((PictureBox)(cntl)).Image != null)
                    {

                        ((PictureBox)(cntl)).Image.Dispose();

                        ((PictureBox)(cntl)).ImageLocation = null;
                    }
                }
                else
                {
                    DisposeImageControls(cntl);
                }
            }

        }

mainCntl is the form which contains the userControl and the userControl consist of a picturebox.

This is where i call the above method:

                    viewImagesForm.ShowDialog();

                    if (viewImagesForm != null && !viewImagesForm.IsDisposed)
                    {
                        viewImagesForm.DisposeImageControls(viewImagesForm);
                        viewImagesForm.Dispose();
                        viewImagesForm = null;
                    }

When I click in a button to re open the form, I get this exception:

StackTrace  "   at System.Drawing.Image.get_FrameDimensionsList()\r\n   at System.Drawing.ImageAnimator.CanAnimate(Image image)\r\n   at System.Drawing.ImageAnimator.ImageInfo..ctor(Image image)\r\n   at System.Drawing.ImageAnimator.Animate(Image image, EventHandler onFrameChangedHandler)\r\n   at System.Windows.Forms.PictureBox.Animate(Boolean animate)\r\n   at System.Windows.Forms.PictureBox.Animate()\r\n   at System.Windows.Forms.PictureBox.OnPaint(PaintEventArgs pe)\r\n   at System.Windows.Forms.Control.PaintWithErrorHandling(PaintEventArgs e, Int16 layer, Boolean disposeEventArgs)\r\n   at System.Windows.Forms.Control.WmPaint(Message& m)\r\n   at System.Windows.Forms.Control.WndProc(Message& m)\r\n   at System.Windows.Forms.Control.ControlNativeWindow.OnMessage(Message& m)\r\n   at System.Windows.Forms.Control.ControlNativeWindow.WndProc(Message& m)\r\n   at System.Windows.Forms.NativeWindow.DebuggableCallback(IntPtr hWnd, Int32 msg, IntPtr wparam, IntPtr lparam)\r\n   at System.Windows.Forms.UnsafeNativeMethods.DispatchMessageA(MSG& msg)\r\n   at System.Windows.Forms.Application.ComponentManager.System.Windows.Forms.UnsafeNativeMethods.IMsoComponentManager.FPushMessageLoop(Int32 dwComponentID, Int32 reason, Int32 pvLoopData)\r\n   at System.Windows.Forms.Application.ThreadContext.RunMessageLoopInner(Int32 reason, ApplicationContext context)\r\n   at System.Windows.Forms.Application.ThreadContext.RunMessageLoop(Int32 reason, ApplicationContext context)\r\n   at System.Windows.Forms.Application.RunDialog(Form form)\r\n   at System.Windows.Forms.Form.ShowDialog(IWin32Window owner)\r\n   at System.Windows.Forms.Form.ShowDialog()\r\n   at ImageView.Presentation.Controller.ViewImagesController.ViewPhotos() in C:\\Workspace\\New Folder (2)\\ ImageView\\Presentation\\Controller\\ViewImagesController.cs:line 227"   string

I think the way I am disposing the picture boxes is incorrect.
Any help or advice will be greatly appreciated.
Thanks

Just so I'm clear, you are instantiating a new instance of your Form (i.e. new SomethingForm();) before each call to ShowDialog();, correct? I tried your code, and it seems to be working. Also, a stack trace is nice, but what is the actual exception you are getting (class and message)?

He's not creating a new form, he's reopening the old one. That's the problem here.

That's what I thought from the first post, then I saw this:

viewImagesForm.ShowDialog();

if (viewImagesForm != null && !viewImagesForm.IsDisposed)
{
    viewImagesForm.DisposeImageControls(viewImagesForm);
    viewImagesForm.Dispose();
    viewImagesForm = null;
}

where he sets viewImagesForm to null. So I wanted to know whether he was getting the reference to the form from somwhere else before viewImagesForm.ShowDialog();, or instantiating a new one.

If that is the case, then Dispose() shouldn't be called on the Form, since unmanaged resources are generally allocated in the constructor. A disposed control (or pretty well any object) should be considered unusable. The same is true for the PictureBox. If you wanted to dispose of a PictureBox after the Form is closed, but reuse the Form afterwards, you would have to instantiate and add the controls outisde of the constructor (in the Load event perhaps). The controls should also be removed from the Form.Controls collection when they are disposed of.

FYI, I tested the code without disposing the Form (or setting the variable to null), and I didn't get any exception. The PictureBox just didn't display anything.

Hi. Thanks for your replies.
I just noticed that the form crashes only when I close the form when the picture box is loading the images. That is the form is still loading the image or the retrieving the im age and I close the form. When I open the form again it crashes. But if I let the image load, and then close the form, it does not crash.
Any advice please?

For starters, could you please answer the questions from my first post?

Just so I'm clear, you are instantiating a new instance of your Form (i.e. new SomethingForm();) before each call to ShowDialog();, correct? I tried your code, and it seems to be working. Also, a stack trace is nice, but what is the actual exception you are getting (class and message)?

Hello. I have been able to solve the problem!
Fix done is:

if (pictureBox != null && pictureBox.Image != null)
            {
                // We don't want to dispose the initial image
                // Hence, need to check if the image is different to initial image
                if (pictureBox.Image.GetHashCode() != pictureBox.InitialImage.GetHashCode())
                {
                    pictureBox.Image.Dispose();
                }
            }
Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.