2014-02-13 58 views
2

我在使用XML填充TreeView層次結構時遇到了「內存不足」問題。我們的XML結構非常複雜,並且不是固定的格式。有多個級別的子節點。我使用遞歸來迭代XML並填充TreeView結構。我試圖調用GC.Collect。清除記憶,但它仍然拋出相同的錯誤。 我正在使用.NET Framework 3.5的C#進行開發。填充TreeView時出現「內存不足」

如果你能幫我找到解決方案,我將不勝感激。

我提供以下

private void addTreeNode(XmlNode xmlNode, TreeNode treeNode) 
{ 
    string attribute = ""; 

    treeView1.ImageList = imageList1; 
    treeViewResponse.ImageList = imageList1; 
    XmlNode xNode; 
    TreeNode tNode; 
    XmlNodeList xNodeList; 
    foo.MoveToFollowing(XPathNodeType.Element); 
    namespaces1 = foo.GetNamespacesInScope(XmlNamespaceScope.All); 
    if (xmlNode.HasChildNodes) 
    { 

     treeNode.ImageIndex = 0; 
     treeNode.SelectedImageIndex = 0; 
     xNodeList = xmlNode.ChildNodes; 
     for (int x = 0; x <= xNodeList.Count - 1; x++) 
     { 
      xNode = xmlNode.ChildNodes[x]; 
      treeNode.Nodes.Add(new TreeNode(xNode.Name)); 
      tNode = treeNode.Nodes[x]; 
      //treeNode.Nodes[x].ImageIndex = -1; 
      addTreeNode(xNode, tNode); 
     } 
    } 
    else 
    { 
     treeNode.ImageIndex = 1; 
     treeNode.NodeFont = new Font("Arial", 8, FontStyle.Bold); 
     treeNode.SelectedImageIndex = 1; 
     treeNode.Text = xmlNode.OuterXml.Trim(); 
    } 
} 
+2

您需要使用較少的內存。例如,不要爲每個節點創建一個「新的字體」,只需創建一個字體並重新使用它即可。每個進程有10,000個圖形對象的限制,並且一個字體被視爲一個圖形對象。 –

+0

剛剛遇到這個問題。 RaymondChen和@Steven Knauber的答案爲我工作,但如果有人感興趣,我發現[這個線程有更深入的討論](http://forum.memprofiler.com/viewtopic.php?t=1254)(顯然這個問題至少從.NET 2.0開始!) – smead

回答

4

至於林峯建議的代碼,我使用的是用於填充樹視圖,您應該構造字體一次和重用。我注意到,即使你這樣做,改變節點字體會立即導致重繪控件,這會導致TreeView除了你提供的字體之外還會構造內部字體。我已經看到了這種情況,這會導致字體句柄的使用速度非常快,以至於垃圾收集器不能足夠快地釋放它們。我認爲這是TreeView中的一個錯誤,它不是很重複,但有時會發生。使用所有應用程序的GDI句柄來保護自己免受Treeview攻擊的方法是在TreeView.BeginUpdate()和TreeView.EndUpdate()調用中包裝一組節點添加或字體更改。

m_treeView.BeginUpdate(); 
try 
{ 
    // TreeNode adds changes here 
} 
finally 
{ 
    m_treeView.EndUpdate(); 
} 

即使添加或更改了多個節點,也只會導致一次重繪。

Steve

+0

這是很有啓發性的。多謝兄弟! –

+0

類似的「臨時內存吞噬」發生在UI框架試圖爲您的數據庫模型動態地進行大量更改時...出於這個原因,當我知道發生了大規模更改時,我必須關閉所有動畫。 –