【发布时间】:2015-07-14 06:43:08
【问题描述】:
我正在开发一个应用程序,其中客户每隔几个月就会遇到一个问题(他们可以通过重新启动应用程序来解决该问题)。堆栈跟踪始终指向调用e.Graphics.Clear() 的覆盖(类继承自Control)OnPaint() 方法的第一行。
我在 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()方法中删除这一行