【问题标题】:System.ComponentModel.Win32Exception: The operation completed successfullySystem.ComponentModel.Win32Exception:操作成功完成
【发布时间】:2009-07-30 22:32:37
【问题描述】:

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

这可能是什么原因?

【问题讨论】:

  • 我在 google 上找到了 1400 次关于此的点击,但没有一个看起来像真正的解释。
  • 我看到这条错误消息是因为一个完全不同的异常 (Microsoft.ActiveDirectory.Management.Commands.GetADPrincipalGroupMembership)。每当错误发生在 Windows API(即非托管代码)中时,就会发生这种情况,并且在检索错误消息以将其添加到(托管)异常之前被覆盖,因为后者正在构建中。引用deleted Wikipedia page, ...
  • "如果程序调用 Win32 函数失败,程序可以调用 GetLastError 来检索描述初始函数调用失败原因的错误代码;但是 GetLastError 仅返回与最后一个系统函数相关的错误代码调用,因此如果程序进行了另一个成功的函数调用(紧接在 GetLastError 之前),则返回的错误代码将为零,表示“操作成功完成”,通常会通过消息框显示给用户。”跨度>

标签: c# .net winforms win32exception


【解决方案1】:

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

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

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

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

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

【讨论】:

  • 好人 Greg 在 stackoverflow 上:解决自己的问题,发布解决方案。
  • 很好的分析,但想看代码sn-p和更多关于“一系列优化”的解释。
  • 好点,ra170,我编辑了问题并列出了之前描述为“一系列优化”的步骤。谢谢!
【解决方案2】:

Windows 对每个进程有 10000 个句柄 的硬性限制。相当无用的异常“操作成功完成”可能表明已达到此限制。

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

不幸的是,对于 WinForms 内部创建的句柄,您几乎无能为力。例如,TreeView 控件大量创建字体句柄使其难以在需要在 UI 中表示非常大的树的场景中使用。

一些有用的链接:

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

【讨论】:

  • 每个进程 10000 个句柄?这是新的和疯狂的,有没有增加这个限制?
  • @AkashKava 这个限制并不是新的——我可能弄错了,但我认为它从 Windows NT 开始就存在。并且它内置在操作系统代码库中,无法从外部更改。
  • 我同意,有一个超过 10k 句柄的进程,当我尝试创建一个新的 WPF 视觉对象( var visual = new DrawingVisual() )时,我得到了上述错误。
  • 目前这两个链接都无法访问
【解决方案3】:

它在极端情况下是由于不处理图像而引起的。您应该在加载位图时使用 IDisposable 来克服这个问题;

using(Bitmap b = Bitmap.FromFile("myfile.jpg"))
{
   //Do whatever
}

【讨论】:

    【解决方案4】:

    我曾经在创建一个巨大的 PictureBox 时遇到过类似的异常。似乎我无法分配足够大的图形。实际上,我所做的是为一个简单的游戏绘制某种地图,并且我有一个放大功能,这基本上创建了一个更大的缓冲区,然后我以更大的比例重新绘制了所有图形。长时间使用此放大功能或玩到足够深的级别会导致此异常。也许您正在创建大量 Graphic 而没有丢弃它们,或者只是一个足够大而无法分配的 Graphic。

    【讨论】:

      【解决方案5】:

      我在 VB.NET 中遇到了同样的问题。 原因很奇怪:

      在奥地利,我们的 Windows 系统通常有一个 , 作为逗号和一个 .作为千位分隔符。 如果这是扭曲的(我认为这是美国的标准),Windows 将抛出此错误。 改变它应该在奥地利解决了整个事情......

      祝你好运!

      【讨论】:

        【解决方案6】:

        发现 this 可能有帮助 - 似乎是图形或控件处置问题

        【讨论】:

          【解决方案7】:

          可能也与内存碎片有关。我们也在应用中使用非托管组件,当非托管组件吃掉所有大的连续块时,可能会出现无法为双缓冲图形分配足够大的缓冲区的问题。

          【讨论】:

            【解决方案8】:

            此外,内存泄漏可能会导致引发异常。例如,由于 this 等 Internet Explorer 错误之一,具有 2-3 个 Web 浏览器的应用程序可能在几分钟内达到 1 GB 以上。

            【讨论】:

              猜你喜欢
              • 2012-01-17
              • 2011-10-01
              • 1970-01-01
              • 1970-01-01
              • 2010-11-26
              • 2012-02-12
              • 1970-01-01
              • 1970-01-01
              • 2018-12-03
              相关资源
              最近更新 更多