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

Moh*_*iri 11 c# gdi+

为什么我得到"GDI +中发生了一般错误"的例外?

IntPtr hicon = tempBitmap.GetHicon();             
Icon bitmapIcon = Icon.FromHandle(hicon);            
return bitmapIcon;
Run Code Online (Sandbox Code Playgroud)

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

在此输入图像描述

Han*_*ant 22

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

Icon.FromHandle的备注部分说:

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

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

  • 它似乎并不痛苦:根据http://msdn.microsoft.com/en-us/library/vstudio/system.drawing.icon.fromhandle(v=vs.90).aspx添加3行似乎有为我解决了这个问题. (7认同)
  • 在 Windows 10 中,您仍会启动任务管理器,但随后会转到“详细信息”选项卡并右键单击列标题以选择“选择列”。此时您可以添加句柄、GDI 对象和用户对象。 (2认同)

Jef*_*f B 5

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

MSDN 上的Icon.FromHandle示例向您展示了方法。不幸的是,它需要 PInvoke:

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

然后在你的方法中:

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

// And then somewhere later...
DestroyIcon(bitMapIcon.Handle);    
Run Code Online (Sandbox Code Playgroud)

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