16

为什么我收到“GDI+ 中发生一般错误”异常?

IntPtr hicon = tempBitmap.GetHicon();             
Icon bitmapIcon = Icon.FromHandle(hicon);            
return bitmapIcon;

当我的应用程序运行超过 30 分钟时发生错误。(我正在转换System.Drawing.BitmapSystem.Drawing.Icon每一秒)

在此处输入图像描述

4

2 回答 2

29

那是由手柄泄漏引起的。您可以使用 TaskMgr.exe 的“进程”选项卡来诊断泄漏。查看 + 选择列并勾选句柄、GDI 对象和用户对象。在程序运行时观察这些列。如果我的猜测是正确的,您将看到您的流程的 GDI 对象值稳步攀升。当它达到 10,000 时,节目就结束了,Windows 拒绝让您泄漏更多对象。

Icon.FromHandle 的备注部分说:

使用此方法时,您必须使用 Win32 API 中的 DestroyIcon 方法处理生成的图标,以确保释放资源。

这是个好建议,但做起来通常很痛苦。您可以在此答案中找到强制 Icon 对象拥有句柄并自动释放它的技巧。相关代码位于“调用私有图标构造函数”部分之后。

于 2012-08-19T13:25:40.930 回答
6

您可能需要清理您的图标。

MSDN 上的Icon.FromHandle示例向您展示了如何操作。不幸的是,它需要 PInvoke:

[System.Runtime.InteropServices.DllImport("user32.dll", CharSet=CharSet.Auto)]
extern static bool DestroyIcon(IntPtr handle);

然后在你的方法中:

IntPtr hicon = tempBitmap.GetHicon();             
Icon bitmapIcon = Icon.FromHandle(hicon);        

// And then somewhere later...
DestroyIcon(bitMapIcon.Handle);    

如果您DestoryIcon在使用它之前调用它,它可能无法正常工作。对于我自己的这个问题的特定实例,我最终保留了对我创建的最后一个图标的引用,然后DestroyIcon在下次生成图标时调用它。

于 2014-04-23T23:01:06.677 回答