c# - 为什么我的表单在尝试加载图像时抛出 OutOfMemory 异常?

标签 c# winforms out-of-memory

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

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

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

最佳答案

使用 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;

并且可能在其他地方,我们看不到 em.Picture 是如何管理的。

此外,更难诊断的是,GDI+ 在引发准确的异常方面非常差。您还可能会因图像数据错误的文件而出现 OOM。您会在this answer中找到这种令人遗憾的行为的原因。 .

关于c# - 为什么我的表单在尝试加载图像时抛出 OutOfMemory 异常?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10769397/

相关文章:

c# - 在已检查和未检查的上下文中编译

c# - 我可以只使用 aspx 和 cs 文件运行 ASP.Net 应用程序吗?

c# - 如何在 C# 中使用 InstaSharp 关注用户

tensorflow - 如何保证训练阶段不会出现OOM?

C# First() 和 Find() 之间的区别

c# - 如何断言一个 Action 被调用

c# - 如何创建控制台应用程序的 exe

c# - 在组合框中显示数据表中的两列

Android:OutofMemoryError:位图大小超出 VM 预算,我看不到任何理由

vb.net - 设置 FileStream.Seek 的位置/索引以检索数据 VB.NET 的 "blocks"