有没有办法加快 winforms 文本框中显示大量文本的速度? 我的应用程序读取一个文件(最大可达 20MB),然后将其显示到文本框 (TextBoxX.Text = fileText;)。
显示文本的过程非常慢,有时需要几分钟。 问题是该应用程序旨在快速向用户显示文件中的大量文本。
有什么方法可以更快地做到这一点吗?也许使用某种缓存?
我知道这个问题现在已经很老了,但我想添加我认为可能对其他人有帮助的信息。
如果设置WordWrap=false,在某些情况下性能会显着提高。当达到最大限制时,它仍然会换行长行。我尝试了一些 90K 长的文本,其中包含一长段 Base64 数据,响应从 16 秒变为 2 秒。
如果您想将大量文本放入
Text
中,则 TextBox
属性是邪恶的。相反,您应该分块读取文件并使用 AppendText()
函数添加它们。
如果您更进一步,将文件读取过程放入
BackgroundWorker
中,逐行读取文件,然后在 ReportProgress 中报告每一行,您可以在那里实现 AppendText(),它应该使一切变得更加顺利。
经过一些编码和测试后,我不得不承认上述方法听起来不错,但是 TextBox 在每次
AppendText()
之后需要太多的渲染时间,这根本不起作用。
但是如果您对使用第 3 方控件没有问题,您应该看看 Scintilla.Net。它对于大文本文件没有任何问题,并且在这些情况下表现得更好。
就我而言,我需要扫描大约100~5000个文件,并一一显示每个文件的信息。
已进行一些改进:
而且,由于扫描单个文件只需要 7 毫秒,因此我构建了一个缓冲区以避免每秒调用 AppendText() 140 次。它看起来像这样:
const int DisplayIntervalInMilliseconds = 100;
string buffer = null;
var lastTimeUpdated = DateTime.Now;
foreach (var fileName in fileNames)
{
progressBar?.ShowProgress(count++);
var cppFile = new CodeFileCpp(fileName);
buffer += cppFile.Show();
var now = DateTime.Now;
if (now - lastTimeUpdated <= new TimeSpan(
0, 0, 0, 0, DisplayIntervalInMilliseconds))
{
continue;
}
textDisplayer.Append(buffer);
buffer = string.Empty;
lastTimeUpdated = now;
}
textDisplayer.Append(buffer);
textDisplayer.Append 调用 TextBox.AppendText()。注意,我们需要在循环结束后再次追加缓冲区,因为循环停止时缓冲区很有可能不为空。
一开始要扫描845个文件,花了2分钟才扫描到500个左右,而且速度越来越慢,我不得不停下来。现在完成以上所有工作,总共需要 2 秒。
我认为只有一种方法 - 构建自己的控件(或者也许有一种)来在框中显示文本的一小部分(就像在远程管理器中,当您打开极大的文件时)。
您定义一个“窗口” - 例如 500 个字母,当您使用滚动条更改位置时,您会更改文本框的主体并显示文本的另一部分。
看看LockWindowUpdate函数,将文本添加到文本框后不要忘记解锁。
http://msdn.microsoft.com/en-us/library/dd145034%28v=vs.85%29.aspx
我认为20Mb的文件即使通过记事本打开也会有明显的延迟。
添加读取数据块的建议(这是大数据的最佳选择..就像它在网络下载中所证明的那样)..
您可以以文件流的形式在读取模式下打开文本文件..然后循环读取 1mb 或更少的字节内容..并将内容添加到文本框。
伪代码:
while(不是文件结尾) { 字符串内容=从流中读取1024*1024字节..将其转换为ascii编码。
文本框.文本+=内容
}
我自己刚刚遇到这个问题,另一种可能的解决方法是使用 RichTextBox。与直觉相反,考虑到与普通 TextBox 相比它可以处理多少内容,将 RichTextBox 的 Text 属性设置为非常大的字符串几乎是瞬时的。
如果您不想编辑文本框中的文本,则只需使用 TextBlock 即可。这样速度更快。
代码更改最小的解决方案是将整个文件内容读取到变量中,然后在每次迭代中调用 Application.DoEvents() 的循环中将内容的“块”附加到文本框。
您可以在加载时显示“正在加载,请稍候...”消息,DoEvents 调用将确保您的应用程序在此期间不会被“冻结”。