【问题标题】:Graphics.Clear() inside of OnPaint() occasionally causes generic GDI+ errorOnPaint() 内的 Graphics.Clear() 偶尔会导致通用 GDI+ 错误
【发布时间】:2015-07-14 06:43:08
【问题描述】:

我正在开发一个应用程序,其中客户每隔几个月就会遇到一个问题(他们可以通过重新启动应用程序来解决该问题)。堆栈跟踪始终指向调用e.Graphics.Clear() 的覆盖(类继承自ControlOnPaint() 方法的第一行。

我在 Microsoft 的文档中读到:

Clear 方法清除图形对象的状态,在图形对象无法更新时不应调用。例如,如果在终端服务器会话中的安全桌面上调用 Clear 方法,则可能会发生 ExternalException,从而使 Graphics 对象处于不一致的状态。

我已验证该应用程序的用户没有从远程计算机上运行该应用程序。 我也读过:

在派生类中重写 OnPaint 时,请务必调用基类的 OnPaint 方法,以便注册的委托接收事件。

应用程序当前未调用基类OnPaint() 是否会导致“GDI+ 中发生一般错误”ExternalException 错误消息?

不幸的是,我对这个问题一无所知,因为我无法重现它,而且它在生产场景中很少发生。谁能提供一些见解?

【问题讨论】:

  • 许多 System.Drawing 对象都是一次性的。不处理它们是非常常见的疏忽。这可以工作很长时间,通常 GC 运行频率足以防止出现问题。直到它没有,然后你会得到像这样的奇怪异常。使用任务管理器,进程选项卡。查看 + 选择列并勾选 GDI 对象。修复您的代码,使数字保持在最多几百个以下。
  • 你可以尝试捕捉错误
  • 我应该在OnPaint() 方法中调用dispose() 而不是clear()
  • 您不应该将dispose() 与您尚未声明的对象一起使用,因此您不能在此处使用e.Graphics.dispose()。我的问题是您使用e.Graphics.Clear() 的原因是什么?
  • 我认为使用e.Graphics.Clear() 的原因是“重置”进度条。我想知道我是否可以简单地从 OnPaint() 方法中删除这一行

标签: .net vb.net


【解决方案1】:

如果创建图形,请始终在Using statement 中使用它:

Using gr As Graphics = Graphics.FromImage(image)

    textSize = gr.MeasureString(myString, myFont) 'sample usage

End Using

另一方面,从不 Dispose() 没有创建的对象。 (包括 Graphics... 的实例)当我们对其进行简化时,在这种情况下,它会在其他地方等待它的“End Using”——在它得到它的“Using”的地方附近。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-03-21
    相关资源
    最近更新 更多