有没有办法加快在winforms文本框中显示大量文字? 我的应用程序读取一个文件(可以大到20MB),然后将其显示到文本框(TextBoxX.Text = fileText;)。
显示文本的过程非常缓慢,有时需要几分钟。 问题是这个应用程序旨在快速向用户显示文件中的大量文本。
有没有办法更快地完成这项工作?也许使用某种缓存?
答案 0 :(得分:9)
我知道这个问题现在已经过时了,但我想补充一些我认为可能对其他人有帮助的信息。
如果设置WordWrap = false,在某些情况下性能会显着提高。当达到最大限制时,它仍将包裹长行。我尝试了一些90K长的文本,其中包括一大块Base64数据,响应从16秒变为2秒。
答案 1 :(得分:3)
如果您想将大量文字放入Text
,TextBox
属性是邪恶的。相反,您应该以块的形式读取文件,并使用AppendText()
函数添加它们。
如果你进一步将文件读取过程放入逐行读入文件的BackgroundWorker
然后报告ReportProgress中的每一行,你可以在那里实现AppendText()并且它应该做的很多平滑。
经过一些编码和测试后,我不得不承认上述方法听起来不错,但TextBox在每个AppendText()
之后需要这么多的渲染时间,这只是不起作用。
但是如果您对使用第三方控件没有任何问题,请查看Scintilla.Net。它对大文本文件没有任何问题,在这些情况下表现更好。
答案 2 :(得分:1)
就我而言,我需要扫描大约 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 秒。
答案 3 :(得分:0)
我认为只有一种方法 - 构建自己的控件(或者可能有一个)来显示文本的小部分(例如在远程管理器中,当你打开极端大文件时)。
您定义了一个“窗口” - 例如500个字母,当您使用滚动条更改位置时,您可以更改yourtextbox的主体并显示文本的另一部分。
答案 4 :(得分:0)
看一下LockWindowUpdate函数,一旦将文本添加到文本框中,别忘了解锁。
http://msdn.microsoft.com/en-us/library/dd145034%28v=vs.85%29.aspx
答案 5 :(得分:0)
我认为即使通过记事本打开,20Mb文件也会有明显的延迟。
添加有关读取数据块的建议(这是大数据的最佳选择......就像在网络下载中证明的那样)..
您可以在读取模式下将文本文件作为文件流打开..然后在循环中读取1mb或更少的字节内容..并将内容添加到文本框中。
伪码:
while(不是文件结尾) { string content =从流中读取1024 * 1024字节..将其转换为ascii编码。
textbox.text + = content
}
答案 6 :(得分:0)
我自己刚遇到此问题,另一种可能的解决方法是使用RichTextBox。与直观相反,考虑到与普通TextBox相比可以处理的更多内容,将RichTextBox的Text属性设置为一个非常大的字符串几乎是即时的。
答案 7 :(得分:-1)
代码变化最小的解决方案是将整个文件内容读入变量,然后在每次迭代中调用Application.DoEvents()的循环中将内容的“块”附加到文本框中。
当它仍在加载时,您可以显示“正在加载请稍候...”消息,DoEvents调用将确保您的应用程序不会同时“冻结”。