WPF:警惕TextBox会占用过多内存

简介: 原文:WPF:警惕TextBox会占用过多内存问题源自这篇文章:WPF的TextBox产生内存泄露的情况。 整个问题是这样的,文章作者演示使用类似下方的代码来不停地像WPF的TextBox控件赋值: for (int i = 0; i
原文: 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会因为频繁修改值而堆积过多的撤销项目项目。就如同Visual Studio的撤销列表一样:

image

这部分项目会占用过多的内存空间。

 

在.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。

目录
相关文章
|
11月前
|
数据可视化 数据处理 C#
WPF技术之TextBox控件
WPF ProgressBar控件用于显示操作的进度。它提供了一个可视化的进度条,用于表示任务的完成程度
93 0
|
11月前
|
C# 数据安全/隐私保护 Windows
WPF技术之TextBox控件
WPF(Windows Presentation Foundation)的TextBox控件是用于用户输入和编辑文本的常见控件
822 0
WPF中给TextBox/TextBlock设置提示文本
WPF中给TextBox/TextBlock设置提示文本
WPF中给TextBox/TextBlock设置提示文本
WPF 点击 Datagrid 中的TextBox 控件获取其所在行的数据
WPF 点击 Datagrid 中的TextBox 控件获取其所在行的数据
|
C#
WPF TextBox自动滚动到最户一行
原文:WPF TextBox自动滚动到最户一行 textBox经常用来显示程序的运行状态或者消息,如何让他自动滚动呢? 在显示消息代码下加一条自动滚动到底部的语句即可:  TextBox1.ScrollToEnd(); (如果要显示垂直滚动条设置VerticalScrollBarVisibility="Auto",如果不显示设置为Hidden) 我用的程序代码如下:   this.
2029 0
|
Java C#
C# WPF Image Source 频繁切换导致垃圾回收不及时导致内存占用不断增加的问题
C# WPF Image Source 频繁切换导致垃圾回收不及时导致内存占用不断增加的问题
2376 0
|
C#
wpf 开发 -TextBox背景自定义-Decorator
首先在app.xaml文件的下面添加以下样式
1662 0
|
C# Windows 数据可视化
WPF使用DynamicDataDisplay.dll显示CPU及内存使用曲线
原文:WPF使用DynamicDataDisplay.dll显示CPU及内存使用曲线 版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/wangshubo1989/article/details/46875243 DynamicDataDisplay.dll是一个添加动态数据到您的Silverlight或WPF应用程序交互的可视化控件。
2715 0
|
C#
WPF TextBox/TextBlock 文本超出显示时,文本靠右显示
原文:WPF TextBox/TextBlock 文本超出显示时,文本靠右显示 文本框显示 文本框正常显示: 文本框超出区域显示:    实现方案 判断文本框是否超出区域 请见《TextBlock IsTextTrimmed 判断文本是否超出》 设置文本布局显示 1.
1616 0
|
C# 编解码
使用不安全代码将 Bitmap 位图转为 WPF 的 ImageSource 以获得高性能和持续小的内存占用
原文:使用不安全代码将 Bitmap 位图转为 WPF 的 ImageSource 以获得高性能和持续小的内存占用 版权声明:本作品采用知识共享署名-非商业性使用-相同方式共享 4.0 国际许可协议进行许可。
1168 0