Jak*_*eta 25 .net c# win32exception winforms
我有时会在运行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)
Run Code Online (Sandbox Code Playgroud)
可能是什么原因造成的?
Jak*_*eta 22
总结一下,我写的自定义网格,基于.Net的DataGridView,使用自定义代码绘制单元格.我的网格中的行可以跨越多个可视页面.(这是业务要求)
问题是.Net为启用了DoubleBuffering的控件预先分配了一个内存缓冲区.对于DataGridViews网格,缓冲区需要相当大,以适应网格中可能存在的大行.在极端情况下,行最多可以跨越32000像素(因为.net限制).项目中的网格宽度通常在500到800像素之间.所以得到的缓冲区可以是(32bpp*800*32000 = ~100MB)
简而言之,系统无法创建兼容的图形对象,因为偶尔它无法保留足够大的缓冲区以适应所需的数据.
为了解决这个问题,我不得不引入一系列优化:
Bra*_*vic 14
Windows 每个进程的硬限制为10000个句柄.相当无益的异常"操作成功完成"可能表示已达到此限制.
如果由于代码中的资源泄漏而发生这种情况,那么您很幸运,因为您至少有机会修复您的代码.
不幸的是,你几乎没有办法在WinForms内部创建的句柄上做.例如,TreeView控件大量创建字体句柄使得在需要在UI中表示非常大的树的场景中很难使用它.
一些有用的链接:
http://support.microsoft.com/kb/327699 http://nomagichere.blogspot.com/2008/03/systemcomponentmodelwin32exception-is.html