为什么我收到“GDI+ 中发生一般错误”异常?
IntPtr hicon = tempBitmap.GetHicon();
Icon bitmapIcon = Icon.FromHandle(hicon);
return bitmapIcon;
当我的应用程序运行超过 30 分钟时发生错误。(我正在转换System.Drawing.Bitmap
为System.Drawing.Icon
每一秒)
那是由手柄泄漏引起的。您可以使用 TaskMgr.exe 的“进程”选项卡来诊断泄漏。查看 + 选择列并勾选句柄、GDI 对象和用户对象。在程序运行时观察这些列。如果我的猜测是正确的,您将看到您的流程的 GDI 对象值稳步攀升。当它达到 10,000 时,节目就结束了,Windows 拒绝让您泄漏更多对象。
Icon.FromHandle 的备注部分说:
使用此方法时,您必须使用 Win32 API 中的 DestroyIcon 方法处理生成的图标,以确保释放资源。
这是个好建议,但做起来通常很痛苦。您可以在此答案中找到强制 Icon 对象拥有句柄并自动释放它的技巧。相关代码位于“调用私有图标构造函数”部分之后。
您可能需要清理您的图标。
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
在下次生成图标时调用它。