繁体   English   中英

RichTextBox中TextRange构造函数的性能

[英]TextRange constructor performance in RichTextBox

我目前正在从事语法突出显示和代码完成项目,并基于RichTextBox进行用户控制。 我在适应RTB的工作方式和所有问题时遇到了一些问题,但是我设法进行了简单的语法突出显示。

简单意味着每次用户键入字符时,我都会突出显示整个文本。 它不应该是快速的或任何东西,但是它太慢了 当我有大约500个字符的文本时,就会出现性能问题,并且对于每个键入的字符,我只对文本进行一次遍历(“ colorInterval”函数在一次遍历中被调用了约100次)。

性能分析说,问题是TextRange构造函数需要大约80%以上的时间,并且每次需要为文本间隔上色时,都会使用它:

private void colorInterval(TextPointer start, TextPointer end)
    {
        TextRange range = new TextRange(start, end);
        if(isFunction(range.Text)) colorAsFunction(range);
        if(isInQuotes(range.Text)) colorAsQuoted(range);
        ...
    }

所以这是我的问题

我是否以这种方式做任何事情都是错误的,还是有办法提高TextRange的性能,回收“范围”对象或类似的东西? 还有什么其他解决方案。

最简单的方法是(如您建议的那样)重用TextRange对象,如果它确实是占用大部分时间的构造函数。 TextRange属性的StartEnd是只读的,但是有一个公共方法Select可以同时更新这两个方法,就像您一直在使用的构造方法一样,使用两个TextPointer对象。

protected TextRange range;

private void colorInterval(TextPointer start, TextPointer end)
{
  if (range == null)
    range = new TextRange(start, end);
  else
    range.Select(start, end);
  ...
}

(注:在决定是否初始化变量之前检查空引用并不像在声明中实例化TextRange那样整洁。不幸的是, TextRange没有公共的空构造函数,而TextPointer没有公共的构造函数。您可以使用一些方法来创建它类构造函数中的虚拟值,以避免此检查。)

在上面,我说过“如果真的是构造函数”。 显然,您正确完成的概要分析突出了构造函数,但它很容易成为构造函数和Select方法的通用例程。

假设您不从多个线程中调用colorInterval ,那么我想说这是一种比您目前节省时间的方法更好的方法,因为(我猜想) colorInterval被频繁调用,并且常量的创建和垃圾回收它留下的后续TextRange对象肯定是效率低下的。

提出此建议后,我强烈建议您离开要在每次要对(例如)单个字符更改做出反应时扫描整个文档的模型。 假设您的目标是> = .net 3.5, RichTextBox提供一个TextChanged事件,该事件报告一个TextChange对象列表,您可以从中确定更改的位置(以及更改所添加或删除的字符)。

当然,这里会有一些工作,因为任何更改都不太可能完全封装突出显示的范围。 TextRange类具有一种查找段落的方法,如果有帮助,可以在其中找到范围的开始和结束。 可能需要存储每个突出显示范围的详细信息,以便您可以快速检查交叉点。

暂无
暂无

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

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