在RichTextBox的TextChange事件上计算日文文本长度时的性能问题

本文关键字:文本 问题 性能 文文本 事件 TextChange RichTextBox 计算 | 更新日期: 2023-09-27 17:55:03

我用c# 2.0编写了自定义的richtextbox。用户将在此文本框中输入日语文本。当用户键入超过300的文本时,它会用黄色突出显示多余的字符。日语文本可以包含半宽字符和全宽字符,我想把半宽字符的大小定为"0.5",全宽字符的大小定为"1"。

下面是我的代码…

Dictionary<int, float> charSizes = new Dictionary<int, float>();
void HighlightingTextBox_TextChanged(object sender, EventArgs e)
{
    int index = this.SelectionStart;
    // Reset highlighting and font.
    HighlightText(0, this.BackColor, true);
    // Highlight Text
    float charCount = 0;
    int highlightIndex = 0;
    string currentText = this.Text;
    for (int k = 0; k < currentText.Length; k++)
    {
        int c = currentText[k];
        if (charCount <= CharacterLimit)
        {
            if (charSizes.ContainsKey(c)) // Use already calculated Size
                charCount = charCount + charSizes[c];
            else
            {
                // Check if character is Half width or Full Width
                string charString = currentText[k].ToString();
                string fullChar = Microsoft.VisualBasic.Strings.StrConv(charString, Microsoft.VisualBasic.VbStrConv.Wide, 1041);
                if (c == (int)fullChar[0])
                {
                    // Ascci value matches after converting to full width. So its Full width char.
                    charCount++;
                    charSizes[c] = 1;
                }
                else
                {
                    charCount = charCount + 0.5f;
                    charSizes[c] = 0.5f;
                }
            }
            highlightIndex++;
        }
        // Enforce "Arial" font for English characters in Japanese text
        this.Select(k, 1);
        this.SelectionFont = (c < 128) ? new Font("Arial", 9.5f) : this.Font;
        this.SelectionLength = 0;
    }
    if (charCount > CharacterLimit)        
        HighlightText(highlightIndex, HighlightColor, false);
    this.SelectionStart = index;
}

private void HighlightText(int selectionStart, Color highlightColor, bool enforceFont)
{
    this.Select(selectionStart, this.Text.Length);
    this.SelectionBackColor = highlightColor;
    if (enforceFont)
        this.SelectionFont = this.Font;
    this.SelectionLength = 0;
}

有什么问题?

此代码适用于前8到10个字符。但在那之后,它的工作速度很慢(花了很多时间,因为它要遍历文本的"每个"字符)。如果用户键入速度快,则需要几秒钟才能在UI上出现新字符。

在这种情况下如何提高性能?还有其他的计算方法吗?

在RichTextBox的TextChange事件上计算日文文本长度时的性能问题

在这种例程中获得性能的最简单方法是:只计算发生了什么变化。

只需比较新旧文本,查看添加或删除了哪些字符,并根据它们修改总数。

你永远不会一次计算多于一个。

——另外,缓存你的Arial 9.5字体,而不是每次都创建一个新的字体。


为了最大限度地减少处理对用户输入的干扰-仅在他们暂停设置的间隔时更新它。

    private Timer _timer = new System.Windows.Forms.Timer();
    private bool _processingText;
    public MyRichTextBox()
    {
        _timer = new Timer();
        _timer.Interval = 1000;
        _timer.Tick += new EventHandler(ProcessText);
    }

    protected override void OnTextChanged(EventArgs e)
    {
        if (_processingText == false)
        {
            _timer.Stop();
            _timer.Start();
        }
    }
    private void ProcessText(object sender, EventArgs e)
    {
        _processingText = true;
        _timer.Stop();
        // Insert your processing logic here
        _processingText = false;
    }