我在运行Windows Forms应用程序很长一段时间时遇到此异常:
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)
原因可能是什么?
答案 0 :(得分:21)
总而言之,我编写的自定义网格基于.Net的DataGridView,使用自定义代码绘制单元格。我的网格中的行可以跨越多个可视页面。 (这是业务要求)
问题在于.Net为启用了DoubleBuffering的控件预先分配了一个内存缓冲区。对于DataGridViews网格,缓冲区需要相当大,以适应网格中可能存在的大行。在极端情况下,行最多可以跨越32000像素(因为.net限制)。项目中的网格宽度通常在500到800像素之间。 因此得到的缓冲区可以是(32bpp * 800 * 32000 = ~100MB)
简而言之,系统无法创建兼容的图形对象,因为偶尔它无法保留足够大的缓冲区以适应所需的数据。
要修复它,我必须引入一系列优化:
答案 1 :(得分:13)
Windows每个进程的硬性限制为 10000个句柄。相当无用的异常“操作成功完成”可能表示已达到此限制。
如果由于您的代码中的资源泄漏而发生这种情况,那么您很幸运,因为您至少有机会修复您的代码。
不幸的是,你几乎没有办法在WinForms内部创建的句柄上做。例如,TreeView控件大量创建字体句柄使得在需要在UI中表示非常大的树的场景中很难使用它。
一些有用的链接:
http://support.microsoft.com/kb/327699 http://nomagichere.blogspot.com/2008/03/systemcomponentmodelwin32exception-is.html
答案 2 :(得分:3)
在创建一个巨大的PictureBox时,我曾遇到类似的异常。似乎我无法分配足够大的图形。实际上,我正在做的是为一个简单的游戏绘制某种地图,我有一个放大功能,基本上创建了一个更大的缓冲区,然后我重新绘制了更大规模的所有图形。长时间使用此放大功能或达到足够深的水平会导致此异常。也许你正在创建大量的图形而不是处理它们,或者只是一个足以不能分配的图形。
答案 3 :(得分:3)
我在VB.NET中遇到了同样的问题。 原因很奇怪:
在奥地利,我们的Windows系统通常有一个逗号和一个。作为成千上万的分离者。 如果这是扭曲的(我认为这是美国的标准),Windows将抛出此错误。 改变它应该在奥地利解决了整个问题......
祝你好运!答案 4 :(得分:2)
找到可能有帮助的this - 似乎是图形或控件处理问题
答案 5 :(得分:2)
在极端情况下由于不处理图像而导致。加载位图时应该使用IDisposable来克服这个问题;
using(Bitmap b = Bitmap.FromFile("myfile.jpg"))
{
//Do whatever
}
答案 6 :(得分:1)
也可能与内存碎片有关。我们在out app中也使用了非托管组件,当非托管组件吃掉所有大的连续块时,可能会出现无法为双缓冲图形分配足够大缓冲区的问题。
答案 7 :(得分:0)
此外,内存泄漏可能导致抛出异常。例如,由于某个Internet浏览器错误(如this),具有2-3个Web浏览器的应用程序可能会在几分钟内达到1 GB以上。