简体   繁体   English

在RichTextBox中格式化文本时的性能问题

[英]Performance issues when formatting text in RichTextBox

I'm creating an editor with simple syntax highlighting using RichTextBox. 我正在创建一个使用RichTextBox进行简单语法高亮的编辑器。 The process of highlighting itself is implemented using following function: 突出显示自身的过程使用以下功能实现:

        TextRange documentRange = new TextRange(rtb.Document.ContentStart, rtb.Document.ContentEnd);
        documentRange.ClearAllProperties();

        .......

        tags.Sort((i, j) => i.Level > j.Level ? 1 : i.Level == j.Level ? 0 : -1);
        Color []_colors=new Color[]{Colors.Blue,Colors.Brown,Colors.BlueViolet,Colors.Crimson,Colors.DarkBlue,
            Colors.Green,Colors.DimGray,Colors.DarkGray,Colors.Maroon,Colors.Navy,Colors.Red};
        foreach (var tag in tags)
        {
            TextRange range = new TextRange(tag.StartPosition, tag.EndPosition);
            range.ApplyPropertyValue(TextElement.ForegroundProperty, new SolidColorBrush(_colors[tag.Level%_colors.Length]));
            range.ApplyPropertyValue(TextElement.FontWeightProperty, FontWeights.Bold);
        }

The problem is, that when I use this approach, when there are a lot of keywords in text, the application's performance suffers significantly, especially that I'm doing this every time RichTextBoxe's text changes. 问题是,当我使用这种方法时,当文本中有很多关键字时,应用程序的性能会受到很大影响,尤其是每次RichTextBoxe的文本发生变化时我都会这样做。

I run the profiler, and in seems that the application spends half of its processor time in documentRange.ClearAllProperties(). 我运行了探查器,似乎应用程序将其处理器时间的一半花费在documentRange.ClearAllProperties()中。

What should I change to improve the permanence of the application? 我应该改变什么来提高应用程序的持久性?

Can anyone provide a good example of fast syntax highlighting using WPF RichTextBox? 任何人都可以使用WPF RichTextBox提供快速语法高亮的好例子吗?

One thing that I would recommend that might help, but probably won't be a complete solution, is to use a timer to call your syntax highlighting code. 我建议的一件事可能会有所帮助,但可能不是一个完整的解决方案,就是使用计时器调用语法高亮代码。 Something like: (psuedo-code) 类似的东西:(伪代码)

OnRichTextChanged() 
{
   StopExisingSyntaxHighlighterTimer();
   StartSyntaxHighlighterTimer(TimeSpan.FromSeconds(5));
}

OnSyntaxHighlighterTimerFired() 
{
   StopExisingSyntaxHighlighterTimer();
   DoSyntaxHighlighting();
}

The idea that you're only doing the syntax highlighting when the user pauses for 5 seconds or more, that way you're not trying to re-highlight the entire RichTextBox with every single key stroke. 您只是在用户暂停5秒或更长时间时才进行语法突出显示的想法,这样您就不会尝试使用每个键击重新突出显示整个RichTextBox。

Also, you might even take this one step further and actually make the DoSyntaxHighlighting cancellable so that if it starts doing the highlighting and the user starts typing again, the highlighter stops processing and waits for the user to stop typing again. 此外,您甚至可以更进一步,实际上使DoSyntaxHighlighting可取消,这样如果它开始执行突出显示并且用户再次开始键入,荧光笔将停止处理并等待用户再次停止键入。

This might look a little funky, since the highlighting will disappear and reappear as they're typing and stopping. 这可能看起来有点时髦,因为突出显示会在他们打字和停止时消失并重新出现。 But it will definitely improve performance. 但它肯定会提高性能。

You can also look at something like AvalonEdit . 您还可以查看类似AvalonEdit的内容

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM