c# - 系统.ComponentModel.Win32Exception : The operation completed successfully

标签 c# .net winforms win32exception

我在长时间运行 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)

这可能是什么原因造成的?

最佳答案

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

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

所以简而言之,系统无法创建兼容的图形对象,因为有时它无法预留足够大的缓冲区来容纳所需的数据。

为了修复它,我不得不引入一系列优化:

  • 将自定义网格中允许的最大行高限制为 1500 像素
  • 更新了缓冲区重新分配代码,使其仅在新缓冲区大小大于现有缓冲区时执行
  • 确保缓冲区不会随着每个数据绑定(bind)而重新分配,而是预先分配到一个合理的大小。
  • 检查了所有代码并确保非托管资源在不使用时得到妥善处置,如此处所建议:http://nomagichere.blogspot.com/2008/03/systemcomponentmodelwin32exception-is.html

关于c# - 系统.ComponentModel.Win32Exception : The operation completed successfully,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1209769/

相关文章:

.net - 用于设置 CurrentCulture 的线程创建事件

c# - ASP.NET MVC : How many repositories?

c# - 加入智能分离器

c# - 这个 ListBox 的枚举器在哪里被循环修改?

c# - 在 C# 中更改多行文本框的特定行

c# - 将 string[] 转换为 int?[]

c# - 在没有 HBM 文件的情况下设置 NHibernate/LINQ 的最快和最简单的方法

c# - 如何在 .NET 3.5+ 中获取用户的 "flat"域名

c# - 删除 wpf 窗口上显示的奇怪的黑色面板或工具栏

c# - 如何在列表中添加时间跨度值