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

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

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

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

在此处输入图像描述

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

Icon.FromHandle的备注部分说:

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

这是一个很好的建议,但通常很痛苦。 你可以找到一个hack来强制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