【问题标题】:Why does my form throw an OutOfMemory exception while trying to load image?为什么我的表单在尝试加载图像时会抛出 OutOfMemory 异常?
【发布时间】:2012-06-01 22:05:33
【问题描述】:

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

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

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

【问题讨论】:

  • 在每张图像上抛出或随机发生的总是相同的图像?
  • @Steve-随机图片会发生这种情况
  • 好吧,这排除了格式错误的图像

标签: c# winforms out-of-memory


【解决方案1】:

当您使用 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 中找到这种令人遗憾的行为的原因。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-08-13
    • 2011-09-16
    • 2014-08-10
    • 1970-01-01
    • 1970-01-01
    • 2022-11-22
    • 2023-03-14
    • 1970-01-01
    相关资源
    最近更新 更多