调用Bitmap.GetHicon时,GDI +中发生了一般错误

时间:2012-08-19 12:58:26

标签: c# gdi+

为什么我收到“GDI +中发生了一般错误”的例外情况?

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

我的应用程序运行超过30分钟时发生错误。 (我每秒都会将System.Drawing.Bitmap转换为System.Drawing.Icon

enter image description here

2 个答案:

答案 0 :(得分:21)

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

Icon.FromHandle的备注部分说:

  

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

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

答案 1 :(得分:2)

您可能需要清理图标。

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