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

发布于 2024-07-29 04:05:21 字数 1235 浏览 9 评论 0 原文

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

这可能是什么原因?

I am getting this exception sometimes while running my Windows Forms app for a long time:

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)

What could be the cause for this?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(8

铃予 2024-08-05 04:05:21

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

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

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

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

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

Just to sum it up, the custom grid I wrote, that is based on the .Net's DataGridView, uses custom code to draw cells. Rows in my grid can span multiple visual pages. (That was a business requirement)

The problem was that .Net pre-allocates a buffer of memory for controls with DoubleBuffering enabled. For DataGridViews grids the buffer needs to be rather large to accommodate possible large rows in the grid. In extreme cases a row can span up to 32000 pixels (because of a .net limitation). Grid widths in the project are usually between 500 and 800 pixels.
So the resulting buffer can be (32bpp * 800 * 32000 = ~100MB)

So in short, the system could not create compatible graphics objects, because occasionally, it could not reserve a buffer large enough to fit the required data.

To fix it I had to introduce a series of optimizations:

  • limited max row height allowed in my custom grid to 1500 pixels
  • updated buffer re-allocation code to only execute when the new buffer size is greater than the existing
  • ensured that the buffers are not reallocated with every data binding, and preallocated to a sensible size.
  • reviewed all code and made sure that unmanaged resources are properly disposed when not in use, as recommended here: http://nomagichere.blogspot.com/2008/03/systemcomponentmodelwin32exception-is.html
笨死的猪 2024-08-05 04:05:21

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

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

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

一些有用的链接:

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

Windows has a hard limit of 10000 handles per process. The rather unhelpful exception "The operation completed successfully" might indicate that this limit was reached.

If this happened because of a resource leak in your code, then you are in luck, as you at least have the opportunity to fix your code.

Unfortunately, there is scarcely little you can do about handles created internally by WinForms. For example, the prolific creation of font handles by TreeView control makes it hard to use in a scenario where very large tree needs to be represented in UI.

Some useful links:

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

白云不回头 2024-08-05 04:05:21

极端情况下是由于没有处理图片造成的。 加载位图时应该使用 IDisposable 来克服这个问题;

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

Its caused in extreme cases by not disposing images. You should make use of IDisposable when loading bitmaps to overcome this;

using(Bitmap b = Bitmap.FromFile("myfile.jpg"))
{
   //Do whatever
}
缪败 2024-08-05 04:05:21

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

I once had a similar exception, when creating a huge PictureBox. It seems that I could not allocate a Graphics big enough. Actually, what I was doing was drawing some sort of map for a simple game, and I had a zoom in functionality, that basically created a bigger buffer and then I redrawed all the graphics in a bigger scale. Playing with this zoom in function for a long time or to a deep enough level caused this exception. Perhaps you are creating lots of Graphics and not dispossing them, or just a Graphic big enough to not be allocatable.

纸短情长 2024-08-05 04:05:21

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

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

祝你好运!

I had the same problem in VB.NET.
The reason for this was weird:

In Austria, our Windows Systems usually have a , as comma and a . as thousands-seperator.
If this is twisted (which is standard in US I think) Windows will throw this Error.
Changing it as it should be in Austria solved the whole thing...

Good luck!

随风而去 2024-08-05 04:05:21

找到这可能有帮助 - 似乎是图形或控件处置问题

Found this which may help - seems to be a Graphics or Control disposal issue

飞烟轻若梦 2024-08-05 04:05:21

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

Might also have something to do with memory fragmentation. We use an unmanaged component in out app as well, and there may be issues with not being able to allocate a large enough buffer for the double-buffered graphics, when the unmanaged component has eaten all the large contiguous blocks.

一梦浮鱼 2024-08-05 04:05:21

此外,内存泄漏可能会导致抛出异常。 例如,由于 Internet Explorer 错误之一(例如

Also, memory leaks can cause the exception to be thrown. For example, an application with 2-3 web browsers could reach over 1 GB in a few minutes, due to one of the internet explorer bugs like this.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文