为什么我的表单在尝试加载图像时会引发内存不足异常

本文关键字:异常 内存不足 图像 加载 表单 我的 为什么 | 更新日期: 2023-09-27 18:35:21

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

用户视图详细信息.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

表格1.cs:

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

此处捕获了"内存不足"异常。发生了什么事情?相同的代码不会在我的另一个应用程序中引发任何异常。

为什么我的表单在尝试加载图像时会引发内存不足异常

当您

使用 Bitmap 类时,OutOfMemoryException 非常常见。 位图可能需要大量内存。 遇到麻烦的一种标准方法是草率地调用其Dispose()方法。 在代码中不使用Dispose()是你在.NET中很容易摆脱的事情,终结器会在你之后清理。 但这往往不适用于位图,因为它们需要大量非托管内存来存储像素数据,但托管内存很少。

代码中至少缺少一个 Dispose() 调用,您没有处理旧的背景图像。 修复:

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

可能在其他地方,我们看不到它们是如何的。图片已管理。

此外,更难诊断的是,GDI+ 在引发准确异常方面非常差。 您还可以从包含错误图像数据的文件中获取 OOM。 你会在这个答案中找到这种令人遗憾的行为的原因。