2013-04-22 40 views
4

我有一個樹視圖和基於TreeView的項目,我有右側的列表視圖。所以幾乎UI是我們的Windows資源管理器的外觀。所以現在我面臨的問題是,當我從列表視圖中刪除大量的對象來到右側時,左側的樹視圖變成部分畫(我可以說小部分)。當我從VS IDE獲得CLR excpetion時,它指向line sampletree.EndUpdate();除了內存不足之外。當我加入的ListView一切下一個項目都正常我的意思是樹狀完全畫 異常我得到是.net中的內存異常winform treeview

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

你有我爲什麼我的TreeView的是隻塗一個samll一部分,並連續修改油漆充分的任何想法?代碼片段顯示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 我使用的字體像這樣

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

這是否漏水GDI資源使

+0

做的winform樹視圖有任何已知的問題,或者任何索引變成-1? – vettori 2013-04-22 13:46:52

+0

同樣的問題在這裏。任務管理器顯示該進程創建了10,000個GDI字體句柄(然後崩潰,最大值爲10,000)。只有當我同時創建很多節點時纔會發生這種情況。 – dacap 2013-07-11 17:10:38

回答

2

這種崩潰的常見原因的任何問題。這通常是由於忘記在任何System.Drawing類對象上調用Dispose()方法造成的。通常情況下,垃圾收集器會在你之後清理,但是,特別是當你使用ownerdraw時,它可能無法經常運行以避免麻煩。當你消耗了10000個GDI對象時,Windows會在你的程序中插入這個插件,結果是kaboom。

您可以從任務管理器輕鬆地診斷此問題。查看+選擇列並勾選句柄,USER對象和GDI對象。在使用過程中,觀察您的流程添加的列。穩步攀升的數字預示着OOM Kaboom。

首先查看您的DrawNode事件處理函數,因爲它可能會被頻繁調用。但也可能由其他繪畫代碼引起。確保您使用語句創建圖形,筆,畫筆,字體等繪圖對象,並使用聲明,以確保它們在使用後處置。你從任務管理器獲得的診斷告訴你什麼時候你在前面。

+0

你可能是正確的,我現在想知道的是當問題出現的時候(treeview切割一半)刪除lot對象後,再次添加單個對象時,一切都會變得正常,原因是什麼? – vettori 2013-04-22 18:23:33

+0

想知道這一點是毫無意義的,明顯更少的數據會導致你忘記處理的句柄更少。使用事實,任務管理器告訴你什麼? – 2013-04-22 18:30:09

+0

任務管理器顯示Handles,USER對象和GDI對象的計數增加,但並不是連續的,它停止了某些值,並開始減少到一些值。我修改了我的問題。當使用字體我didtn使用使用語句 – vettori 2013-04-22 18:35:54

1

我剛碰到同樣的問題。它似乎只發生在晚於XP的Windows系統中,並且當我刪除BeginUpdate()EndUpdate()調用時,它不會發生。

因此,作爲一種解決方法,我會說嘗試刪除BeginUpdate()EndUpdate()調用。這確實意味着在更新節點時可能會出現一些視覺障礙,但從正面來看,它不會崩潰。這無疑是一場淨勝。

我在MSDN/Connect上找不到任何解決此問題的問題,我現在沒有時間將自包含的測試用例組合在一起,但我確實認爲這是處理批量更新中的錯誤在更高版本的Windows中使用TreeViews。

+0

另外,如果你只是用'myTreeView.Visible = false'代替'BeginUpdate()',用'myTreeView.Visible = true'代替'EndUpdate()' - 你可以避免所有的屏幕閃爍,並且不會遇到bug。 (這似乎也有相當不錯的表現。) – 2016-02-12 14:45:20