System.ComponentModel.Win32Exception:操作成功完成

Jak*_*eta 25 .net c# win32exception winforms

我有时会在运行Windows窗体应用程序时遇到此异常:

System.ComponentModel.Win32Exception: The operation completed successfully
   at System.Drawing.BufferedGraphicsContext.CreateCompatibleDIB(IntPtr hdc, IntPtr hpal, Int32 ulWidth, Int32 ulHeight, IntPtr& ppvBits)
   at System.Drawing.BufferedGraphicsContext.CreateBuffer(IntPtr src, Int32 offsetX, Int32 offsetY, Int32 width, Int32 height)
   at System.Drawing.BufferedGraphicsContext.AllocBuffer(Graphics targetGraphics, IntPtr targetDC, Rectangle targetRectangle)
   at System.Drawing.BufferedGraphicsContext.AllocBufferInTempManager(Graphics targetGraphics, IntPtr targetDC, Rectangle targetRectangle)
   at System.Drawing.BufferedGraphicsContext.Allocate(IntPtr targetDC, Rectangle targetRectangle)
   at System.Windows.Forms.Control.WmPaint(Message& m)
   at System.Windows.Forms.Control.WndProc(Message& m)
   at System.Windows.Forms.DataGridView.WndProc(Message& m)
   at System.Windows.Forms.Control.ControlNativeWindow.OnMessage(Message& m)
   at System.Windows.Forms.Control.ControlNativeWindow.WndProc(Message& m)
   at System.Windows.Forms.NativeWindow.Callback(IntPtr hWnd, Int32 msg, IntPtr wparam, IntPtr lparam)
Run Code Online (Sandbox Code Playgroud)

可能是什么原因造成的?

Jak*_*eta 22

总结一下,我写的自定义网格,基于.Net的DataGridView,使用自定义代码绘制单元格.我的网格中的行可以跨越多个可视页面.(这是业务要求)

问题是.Net为启用了DoubleBuffering的控件预先分配了一个内存缓冲区.对于DataGridViews网格,缓冲区需要相当大,以适应网格中可能存在的大行.在极端情况下,行最多可以跨越32000像素(因为.net限制).项目中的网格宽度通常在500到800像素之间.所以得到的缓冲区可以是(32bpp*800*32000 = ~100MB)

简而言之,系统无法创建兼容的图形对象,因为偶尔它无法保留足够大的缓冲区以适应所需的数据.

为了解决这个问题,我不得不引入一系列优化:

  • 我自定义网格中允许的最大行高限制为1500像素
  • 更新的缓冲区重新分配代码仅在新缓冲区大小大于现有缓冲区时执行
  • 确保缓冲区不会与每个数据绑定重新分配,并预先分配到合理的大小.
  • 审查所有的代码,并确保非托管资源的正确在不使用时,这里推荐配置:http://nomagichere.blogspot.com/2008/03/systemcomponentmodelwin32exception-is.html

  • stackoverflow上的Good Guy Greg:解决了自己的问题,POSTS SOLUTION. (21认同)

Bra*_*vic 14

Windows 每个进程的硬限制为10000个句柄.相当无益的异常"操作成功完成"可能表示已达到此限制.

如果由于代码中的资源泄漏而发生这种情况,那么您很幸运,因为您至少有机会修复您的代码.

不幸的是,你几乎没有办法在WinForms内部创建的句柄上做.例如,TreeView控件大量创建字体句柄使得在需要在UI中表示非常大的树的场景中很难使用它.

一些有用的链接:

http://support.microsoft.com/kb/327699 http://nomagichere.blogspot.com/2008/03/systemcomponentmodelwin32exception-is.html