Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Out of memory exception in .net winform treeview

I have a treeview and based on items of treeview i have listview on right side. SO almost UI is our windows Explorer kind of appearance. So now the problem i am facing is when i delete large number of objects from listview coming right side, the treeview on the left side became partially painted(small portion i can say).When i attahced CLR excpetion from VS IDE ,it point to the line sampletree.EndUpdate(); with an exception out of memory. When i add a next item in listview everything come normal i mean treeview is fully painted Exception i am getting is

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()

Do you have any idea why i my treeview is painted only a samll part and successive modification paints fully? code snippet is shown belowe

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

UPDATE I am using Font like this way

case State.Modified:
                     NodeFont = new Font(TreeView.Font, FontStyle.Bold);
break;

Does that make any issues

like image 996
vettori Avatar asked Apr 22 '13 12:04

vettori


1 Answers

This kind of crash is commonly caused by leaking GDI resources. Which is very commonly caused by forgetting to call the Dispose() method on any System.Drawing class object. Usually the garbage collector cleans up after you but, especially when you use ownerdraw, it might not run often enough to keep you out of trouble. Windows pulls the plug on your program when you've consumed 10,000 GDI objects, the kaboom is the result.

You can easily diagnose this from Task Manager. View + Select Columns and tick Handles, USER objects and GDI objects. Observe those added columns for your process while you are using it. A steadily climbing number predicts the OOM Kaboom.

Look in your DrawNode event handler first since it is likely to be called frequently. But it can be caused by other painting code as well. Ensure you create drawing objects like Graphics, Pen, Brush, Font, etc with the using statement so they are guaranteed to be disposed after usage. The diagnostic you get from Task Manager tells you when you're ahead.

like image 148
Hans Passant Avatar answered Oct 15 '22 22:10

Hans Passant