user1134487
user1134487

Reputation:

Why does my form throw an OutOfMemory exception while trying to load image?

I have an application that saves User Information with Image into a data base. Admin can access the information those are already saved through a different form view. Clicking on the List Box item will display the details with Image retrieved from the database.

UserViewDetails.cs:

private void lbEmp_SelectedIndexChanged(object sender, EventArgs e)
{
    try
    {
        if (lbEmp.SelectedIndex != -1)
        {
            em.Emp_ID = Convert.ToInt32(lbEmp.SelectedValue);
            em.SelectById();
            if (!em.EmptyPhoto)
                pbEmp.BackgroundImage = em.Picture;
            else
                pbEmp.BackgroundImage = null;

            txtEmpName.Text = em.Emp_Name;
            txtImagePath.Text = em.ImgPath;
            cmbEmpType.SelectedText = em.EmployeeType;
            cmbCountry.SelectedValue = em.CountryID;
            cmbCity.SelectedValue = em.CityID;
        }
    }
    catch (Exception) { }
}

This form is called from the parent form Form1:

Form1.cs:

try
{
    var vi = new Admin.frmViewEmployeeInfo();
    vi.ShowDialog();
}
catch (Exception ex)
{
    Console.WriteLine(ex.Message);
}

Here, an "out of memory" exception is caught. What is happening? The same code doesn't throw any exception in another application of mine.

Upvotes: 2

Views: 325

Answers (1)

Hans Passant
Hans Passant

Reputation: 941217

An OutOfMemoryException is pretty common when you use the Bitmap class. Bitmaps can require a lot of memory. One standard way to get in trouble is being sloppy about calling its Dispose() method. Not using Dispose() in your code is something you'll get away easily in .NET, finalizers will clean up after you. But that tends to not work well with bitmaps because they take a lot of unmanaged memory to store the pixel data but very little managed memory.

There is at least one Dispose() call missing in your code, you are not disposing the old background image. Fix:

em.SelectById();
if (pbEmp.BackgroundImage != null) pbEmp.BackgroundImage.Dispose();    // <== here
if (!em.EmptyPhoto)
    pbEmp.BackgroundImage = em.Picture;
else
    pbEmp.BackgroundImage = null;

And possibly in other places, we can't see how em.Picture is managed.

Also, and much harder to diagnose, is that GDI+ is pretty poor at raising accurate exceptions. You can also get OOM from a file with bad image data. You'll find a reason for that regrettable behavior in this answer.

Upvotes: 5

Related Questions