vet*_*ori 5 c# treeview listview out-of-memory visual-studio-2010
我有一个树视图,基于树视图的项目,我在右侧有列表视图。因此,几乎UI是我们Windows Explorer的一种外观。所以现在我面临的问题是,当我从右侧的列表视图中删除大量对象时,左侧的树形视图被部分绘制了(我可以说很小的一部分)。当我从VS IDE附加CLR响应时,它指向行sampletree.EndUpdate(); 除了内存不足。当我在列表视图中添加下一个项目时,一切都正常了,这意味着树形视图已完全绘制完毕,异常是
System.OutOfMemoryException occurred
Message=Out of memory.
Source=System.Drawing
StackTrace:
at System.Drawing.Graphics.FromHdcInternal(IntPtr hdc)
at System.Drawing.Font.ToLogFont(Object logFont)
at System.Drawing.Font.ToHfont()
at System.Windows.Forms.Control.FontHandleWrapper..ctor(Font font)
at System.Windows.Forms.OwnerDrawPropertyBag.get_FontHandle()
at System.Windows.Forms.TreeView.CustomDraw(Message& m)
at System.Windows.Forms.TreeView.WmNotify(Message& m)
at System.Windows.Forms.TreeView.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.DebuggableCallback(IntPtr hWnd, Int32 msg, IntPtr wparam, IntPtr lparam)
at System.Windows.Forms.UnsafeNativeMethods.SendMessage(HandleRef hWnd, Int32 msg, IntPtr wParam, IntPtr lParam)
at System.Windows.Forms.Control.SendMessage(Int32 msg, IntPtr wparam, IntPtr lparam)
at System.Windows.Forms.Control.ReflectMessageInternal(IntPtr hWnd, Message& m)
at System.Windows.Forms.Control.WmNotify(Message& m)
at System.Windows.Forms.Control.WndProc(Message& m)
at System.Windows.Forms.ScrollableControl.WndProc(Message& m)
at System.Windows.Forms.UserControl.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.DebuggableCallback(IntPtr hWnd, Int32 msg, IntPtr wparam, IntPtr lparam)
at System.Windows.Forms.UnsafeNativeMethods.CallWindowProc(IntPtr wndProc, IntPtr hWnd, Int32 msg, IntPtr wParam, IntPtr lParam)
at System.Windows.Forms.NativeWindow.DefWndProc(Message& m)
at System.Windows.Forms.Control.DefWndProc(Message& m)
at System.Windows.Forms.Control.WndProc(Message& m)
at System.Windows.Forms.TreeView.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.DebuggableCallback(IntPtr hWnd, Int32 msg, IntPtr wparam, IntPtr lparam)
at System.Windows.Forms.UnsafeNativeMethods.SendMessage(HandleRef hWnd, Int32 msg, Int32 wParam, Int32 lParam)
at System.Windows.Forms.Control.EndUpdateInternal(Boolean invalidate)
at System.Windows.Forms.TreeView.EndUpdate()
Run Code Online (Sandbox Code Playgroud)
您是否知道为什么我的树状视图仅绘制了一个samll零件,而随后的修改又完全绘制了?代码段如下所示
if( ( values != null ) &&
( values .OverallState != ToBeDeleted ) &&
( values .OverallState != .Deleted ) )
{
TreeView tree = this.TreeView;
if( tree != null )
{
tree.BeginUpdate();
}
TryUpdate();
TryPopulate();
if( tree != null )
{
tree.EndUpdate(); // here exception coming
}
}
Run Code Online (Sandbox Code Playgroud)
更新 我正在以这种方式使用字体
case State.Modified:
NodeFont = new Font(TreeView.Font, FontStyle.Bold);
break;
Run Code Online (Sandbox Code Playgroud)
那有什么问题吗
这种崩溃通常是由于 GDI 资源泄漏造成的。这通常是由于忘记调用任何 System.Drawing 类对象上的 Dispose() 方法而引起的。通常垃圾收集器会在您之后进行清理,但是,特别是当您使用ownerdraw时,它可能不会经常运行以让您摆脱麻烦。当您消耗了 10,000 个 GDI 对象时,Windows 就会终止您的程序,结果就是 kaboom。
您可以从任务管理器轻松诊断此问题。查看 + 选择列并勾选句柄、USER 对象和 GDI 对象。在使用流程时,请观察流程中添加的那些列。稳步攀升的数字预示着 OOM Kaboom。
首先查看您的 DrawNode 事件处理程序,因为它可能会被频繁调用。但它也可能是由其他绘画代码引起的。确保使用 using语句创建绘图对象,如 Graphics、Pen、Brush、Font 等,以便保证它们在使用后被处理。从任务管理器获得的诊断信息会告诉您何时领先。