2

我有一个将用户信息与图像一起保存到数据库中的应用程序。管理员可以通过不同的表单视图访问已保存的信息。单击列表框项目将显示从数据库中检索到的带有图像的详细信息。

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) { }
}

此表单从父表单调用Form1

Form1.cs:

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

在这里,捕获了“内存不足”异常。怎么了?相同的代码不会在我的另一个应用程序中引发任何异常。

4

1 回答 1

6

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.

于 2012-05-26T20:38:18.347 回答