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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/1209769/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-06 10:59:24  来源:igfitidea点击:

System.ComponentModel.Win32Exception: The operation completed successfully

c#.netwinformswin32exception

提问by Jakub Kaleta

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

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

What could be the cause for this?

这可能是什么原因?

采纳答案by Jakub Kaleta

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)

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

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)

问题是 .Net 为启用了 DoubleBuffering 的控件预先分配了内存缓冲区。对于 DataGridViews 网格,缓冲区需要相当大以容纳网格中可能的大行。在极端情况下,一行最多可以跨越 32000 个像素(由于 .net 限制)。项目中的网格宽度通常在 500 到 800 像素之间。所以得到的缓冲区可以是 (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
  • 我的自定义网格中允许的最大行高限制为 1500 像素
  • 更新的缓冲区重新分配代码仅在新缓冲区大小大于现有缓冲区时执行
  • 确保缓冲区不会在每次数据绑定时重新分配,并预先分配到合理的大小。
  • 查看所有代码并确保在不使用时正确处理非托管资源,如此处推荐的那样:http: //nomagichere.blogspot.com/2008/03/systemcomponentmodelwin32exception-is.html

回答by zebrabox

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

发现可能有帮助 - 似乎是图形或控制处理问题

回答by Marc

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.

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

回答by Marc

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

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

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

回答by Branko Dimitrijevic

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

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

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.

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

Some useful links:

一些有用的链接:

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

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

回答by Alejandro Piad

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.

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

回答by HI_

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

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

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...

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

Good luck!

祝你好运!

回答by iCantSeeSharp

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.

此外,内存泄漏会导致抛出异常。例如,用2-3 Web浏览器应用程序可以在几分钟内达到超过1 GB时,Internet Explorer蝽象由于一个这个