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

问题描述 投票:0回答:9

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

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

有什么方法可以更快地做到这一点吗?也许使用某种缓存?

c# performance textbox
9个回答
23
投票

我知道这个问题现在已经很老了,但我想添加我认为可能对其他人有帮助的信息。

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


4
投票

如果您想将大量文本放入

Text
中,则
TextBox
属性是邪恶的。相反,您应该分块读取文件并使用
AppendText()
函数添加它们。

如果您更进一步,将文件读取过程放入

BackgroundWorker
中,逐行读取文件,然后在 ReportProgress 中报告每一行,您可以在那里实现 AppendText(),它应该使一切变得更加顺利。

更新

经过一些编码和测试后,我不得不承认上述方法听起来不错,但是 TextBox 在每次

AppendText()
之后需要太多的渲染时间,这根本不起作用。

但是如果您对使用第 3 方控件没有问题,您应该看看 Scintilla.Net。它对于大文本文件没有任何问题,并且在这些情况下表现得更好。


2
投票

就我而言,我需要扫描大约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 秒。


0
投票

我认为只有一种方法 - 构建自己的控件(或者也许有一种)来在框中显示文本的一小部分(就像在远程管理器中,当您打开极大的文件时)。

您定义一个“窗口” - 例如 500 个字母,当您使用滚动条更改位置时,您会更改文本框的主体并显示文本的另一部分。


0
投票

看看LockWindowUpdate函数,将文本添加到文本框后不要忘记解锁。

http://msdn.microsoft.com/en-us/library/dd145034%28v=vs.85%29.aspx


0
投票

我认为20Mb的文件即使通过记事本打开也会有明显的延迟。

添加读取数据块的建议(这是大数据的最佳选择..就像它在网络下载中所证明的那样)..

您可以以文件流的形式在读取模式下打开文本文件..然后循环读取 1mb 或更少的字节内容..并将内容添加到文本框。

伪代码:

while(不是文件结尾) { 字符串内容=从流中读取1024*1024字节..将其转换为ascii编码。

文本框.文本+=内容

}


0
投票

我自己刚刚遇到这个问题,另一种可能的解决方法是使用 RichTextBox。与直觉相反,考虑到与普通 TextBox 相比它可以处理多少内容,将 RichTextBox 的 Text 属性设置为非常大的字符串几乎是瞬时的。


0
投票

如果您不想编辑文本框中的文本,则只需使用 TextBlock 即可。这样速度更快。


-2
投票

代码更改最小的解决方案是将整个文件内容读取到变量中,然后在每次迭代中调用 Application.DoEvents() 的循环中将内容的“块”附加到文本框。

您可以在加载时显示“正在加载,请稍候...”消息,DoEvents 调用将确保您的应用程序在此期间不会被“冻结”。

© www.soinside.com 2019 - 2024. All rights reserved.