我们遇到了某种与.NET运行时相关的图形问题。偶尔,我们应用程序中所有GroupBox的边框和所有NumericUpDowns的箭头都会消失。看起来他们因为某些原因停止重新绘制,因为NumericUpDowns有时会出现箭头所在的图形垃圾。
我们怀疑多次重启应用程序后发生错误。一旦出现问题,重新启动应用程序无济于事。但关闭所有.NET进程并重新启动应用程序会使问题消失,这表明.NET运行时存在问题。
我们的应用程序是使用VS 2008 SP1开发的WinForms应用程序,目标是.NET 3.5。它以经典模式(客户公司策略)在Windows XP SP3上运行。
我搜索过其他有类似问题的人,但大多数点击涉及GroupBoxes的自定义绘制事件。我们的控件很简单 - 根本不使用任何油漆事件。
编辑:如何故意耗尽桌面堆来重现问题?我一直在玩任务管理器和GdiUsage,同时创建像疯了一样的笔,画笔和字体。当然不要调用dispose,而是将它们存储在列表中以避免垃圾回收。尽管如此,在使用随机颜色创建10万支笔后,根据监视工具,我只有几个对象。List<Pen> pens = new List<Pen>();
Random rnd = new Random();
for(int i = 0; i < 100000; i++)
pens.Add(new Pen(Color.FromArgb(rnd.Next())));
答案 0 :(得分:2)
这是泄漏句柄的程序的标志。 Windows为计算机上运行的所有程序的GDI和User对象维护一个堆。每个进程都有10,000个句柄的配额,但是一些泄漏或繁重的程序可以使堆满容量。一旦发生这种情况,用笔绘制边框(例如)的请求将失败,并且东西停止绘制。这并不总是被检查,特别是在本机代码中。
您可以使用Taskmgr.exe,进程选项卡对其进行诊断。使用View + Select Columns并勾选Handles,USER Objects和GDI Objects。在使用该程序时,请注意一个包含大量这些(数百个)并且数量稳步增长的程序。
如果不对像钢笔,画笔,字体,位图等一次性对象使用Dispose()或 using 语句,则可以在.NET程序中泄漏句柄。并且当该程序没有使用足够的内存来触发垃圾收集时,终结器可以释放句柄。