WPF:警惕TextBox會占用過多內存


問題源自這篇文章:WPF的TextBox產生內存泄露的情況。

  整個問題是這樣的,文章作者演示使用類似下方的代碼來不停地像WPF的TextBox控件賦值:

for (int i = 0; i < 10000; i++)

{

    //tbx是界面上的TextBox變量

    tbx.Text += string.Format("{0}\n", i);

}

  然后會出現程序占用過多內存的問題。

  很快在那篇文章的評論中有人指出這個和WPF沒有關系,因為頻繁得拼接字符串會產生過多重復字符串對象,即使不顯示在TextBox控件上,也會會占用過多內存的。

  但是原文作者又在回復中講到他做了相關測試,但是卻不會出現占用非常多的內存的情況。

  最后問題不了了之。

  我做了下測試,一種是不斷拼接字符串並顯示在TextBox中:

//我們就拿個小數字1萬來做示例

for (int i = 0; i < 10000; i++)

{

    //tbx是界面上的TextBox變量

    tbx.Text += string.Format("{0}\n", i);

}

  程序運行后任務管理器顯示55.5 MB的內存。(環境:.NET 4.5/Debug編譯/64位)

  接着測試另一種情況:先拼接字符串,最后才顯示在TextBox中:

var str = String.Empty;

//我們就拿個小數字1萬來做示例

for (int i = 0; i < 10000; i++)

{

    //tbx是界面上的TextBox變量

    str += String.Format("{0}\n", i);

}

tbx.Text = str;

  運行后顯示24.1 MB。

  如果把最后一句刪掉,也就是根本不在TextBox中顯示。運行后是23.4 MB。

  很明顯,整個問題確實是和WPF有關系的,但也不是因為原文作者認為的字符串拼接所造成的。真正的問題是TextBox(更准確地說是其父類:TextBoxBase)的UndoLimit屬性。也就是說TextBox會因為頻繁修改值而堆積過多的撤銷項目項目。

  這部分項目會占用過多的內存空間。

  在.NET 3.5和4.0:TextBoxBase.UndoLimit的值默認是-1。代表如果內存夠用的話,撤銷列表會無限大。(這個有點恐怖)

  在.NET 4.5中:TextBoxBase.UndoLimit的值默認是100。

  我們可以吧TextBoxBase.UndoLimit設置成0(或者把IsUndoEnabled設置成False),也就是命令TextBox不支持撤銷功能。再次運行第一次的代碼:

//禁止撤銷

tbx.UndoLimit = 0;

for (int i = 0; i < 10000; i++)

{

    //tbx是界面上的TextBox變量

    tbx.Text += string.Format("{0}\n", i);

}

  運行后,任務管理器顯示29.4 MB(幾秒后又變成了24 MB)。而沒有設置UndoLimit,也就是.NET 4.5中默認值是100的情況下,占用內存則能飆升到55.5 MB。在非.NET 3.5或者4下可能會更大,因為默認是沒有限制的。

  那么問題的解決方案是:

  適當設置WPF的TextBox.UndoLimit(尤其是.NET 3.5/4.0環境下,默認值-1太可怕了)。當然這僅僅應用在頻繁設置TextBox值的情況下,如果沒有此類情況,無需擔心。另外也要注意如果要進行頻繁字符串拼接操作,請使用TextBoxBase.AppendText或者StringBuilder。

  本文來自劉圓圓博客,原文地址:http://www.cnblogs.com/mgen/archive/2013/02/24/2924558.html


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM