有没有办法加快在winforms文本框中显示大量文本?

时间:2010-12-09 12:11:56

标签: c# performance textbox

有没有办法加快在winforms文本框中显示大量文字? 我的应用程序读取一个文件(可以大到20MB),然后将其显示到文本框(TextBoxX.Text = fileText;)。

显示文本的过程非常缓慢,有时需要几分钟。 问题是这个应用程序旨在快速向用户显示文件中的大量文本。

有没有办法更快地完成这项工作?也许使用某种缓存?

8 个答案:

答案 0 :(得分:9)

我知道这个问题现在已经过时了,但我想补充一些我认为可能对其他人有帮助的信息。

如果设置WordWrap = false,在某些情况下性能会显着提高。当达到最大限制时,它仍将包裹长行。我尝试了一些90K长的文本,其中包括一大块Base64数据,响应从16秒变为2秒。

答案 1 :(得分:3)

如果您想将大量文字放入TextTextBox属性是邪恶的。相反,您应该以块的形式读取文件,并使用AppendText()函数添加它们。

如果你进一步将文件读取过程放入逐行读入文件的BackgroundWorker然后报告ReportProgress中的每一行,你可以在那里实现AppendText()并且它应该做的很多平滑。

更新

经过一些编码和测试后,我不得不承认上述方法听起来不错,但TextBox在每个AppendText()之后需要这么多的渲染时间,这只是不起作用。

但是如果您对使用第三方控件没有任何问题,请查看Scintilla.Net。它对大文本文件没有任何问题,在这些情况下表现更好。

答案 2 :(得分:1)

就我而言,我需要扫描大约 100~5000 个文件,并一一显示每个文件的信息。

进行了一些改进:

  1. WordWrap=false(如@DDRider62 所说)
  2. 使用 TextBox.AppendText() 而不是 Text(如@Oliver 所说)。

此外,由于扫描单个文件只用了 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调用将确保您的应用程序不会同时“冻结”。