C# 在richTextBox1中突出显示匹配字符串时应用程序无响应;输入大的.txt文件

C# 在richTextBox1中突出显示匹配字符串时应用程序无响应;输入大的.txt文件,c#,winforms,C#,Winforms,我正在创建一个简单的日志解析/读取应用程序,当试图突出显示匹配的字符串用户定义的输入和报告在richTextBox1中找到的日志文件行字符串(对于1.5Mb或更大的文本文件)时,该应用程序将变得无响应。小文本文件工作正常。匹配的线条似乎显示得很好。当越来越多地找到匹配的字符串时,尝试突出显示匹配的字符串时存在问题 //application has user select *.txt file and assign contents to string[] logContents, not st

我正在创建一个简单的日志解析/读取应用程序,当试图突出显示匹配的字符串用户定义的输入和报告在richTextBox1中找到的日志文件行字符串(对于1.5Mb或更大的文本文件)时,该应用程序将变得无响应。小文本文件工作正常。匹配的线条似乎显示得很好。当越来越多地找到匹配的字符串时,尝试突出显示匹配的字符串时存在问题

//application has user select *.txt file and assign contents to string[] logContents, not streaming file.
//list of matched strings is made
//matched strings are displayed in richTextBox1

StringBuilder RTBtext = new StringBuilder(richTextBox1.Text);
if (displayMatched != null && displayMatched.Length > 0)
{
    //displays line of log file that matched the entered string
    for (int s = 0; s < displayMatched.Length; s++)
    {
        RTBtext.Append(displayMatched[s] + Environment.NewLine);
    }
}
richTextBox1.Text = RTBtext.ToString();

//newline \n added between matched line to increase readability

//Performance debugging shows "hot lines" with large CPU usage start here:
while (index < richTextBox1.Text.ToUpper().LastIndexOf(this.userInput1))
{
    richTextBox1.Find(this.userInput1, index, richTextBox1.Text.Length,RichTextBoxFinds.None);
    richTextBox1.SelectionColor = Color.White;
    richTextBox1.SelectionBackColor = Color.Blue;
    index = richTextBox1.Text.ToUpper().IndexOf(this.userInput1, index) + 1;
}
程序另一部分中类似样式的循环执行时不会出现问题。我在索引方面有问题吗?是什么让CPU工作得这么辛苦?性能调试状态System.Windows.Forms.RichTextBox.get_Text;这是最大的瓶颈

我尝试过richTextBox1.SuspendLayout和ResumeLayout,但运气不佳,也尝试过RTB1.SuspendPaint/ResumePaint


是否可以一次只高亮显示(例如)大约200行匹配的字符串,然后继续使用richTextBox1.VScrollBar?如果是这样,实现这一点的最佳方法是什么?

根据我的经验,RichTextBox不能很好地处理一次性加载的大量MB+文本

我的建议是在调用搜索操作时直接处理文本文件,并将所有匹配字节偏移量和长度存储到单独的hashset/字典中

一旦有了行号和字节偏移量的集合,就可以根据滚动位置动态地将文本写入RichTextBox。每次向RTB追加新文本时,都会检查在上一步中创建的哈希集中的字节位置。如果您找到一个匹配的字节偏移量,您可以继续并在此时标记文本。在添加RTB时,不要忘记删除RTB开头的文本

我个人处理此应用程序的方式是,除了上述内容之外,还有一个单独的摘要视图,其中包含匹配的行号及其内容。这样,我就可以对所有匹配的文档拥有类似grep的视图。当单击摘要视图匹配项时,它会将RTB主视图滚动到文档中的该点,以便我可以检查关注项周围的条目


我以前使用过类似的技术来处理千兆字节大小的日志文件。

这真的是您的工作代码吗?richTextBox1.Findthis.userInput1,索引,richTextBox1.Text.Length,RichTextBoxFinds.None;返回一个不使用的整数。它不应该选择文本。你可以做一些事情来改善我的想法。您可以保存richTextBox1.Text.ToUpper的值,并对其进行操作。每次调用此方法时,它都必须分配一个新字符串,并对每个字符进行操作。我还将缓存richTextBox1.Text.ToUpper.LastIndexOfthis.userInput1的值,这样就不会在每次运行循环时重新计算它。这将有助于减少CPU重新计算值所需的工作量。必须将richTextBox.Text.ToUpper表达式移出循环。当你这样做的时候,请检查并禁用窗口更新。谢谢@Bob,我会投票支持你,但我没有足够的声誉。我想我明白你的方向和逻辑;但是,您可以提供一个有关您描述的滚动功能的代码块示例。