【问题标题】:C# Application Becomes Slow and Unresponsive as String in Multiline Textbox Grows随着多行文本框中的字符串增长,C# 应用程序变得缓慢且无响应
【发布时间】:2010-01-13 15:59:57
【问题描述】:

我有一个 C# 应用程序,其中将大量信息添加到文本框以显示给用户。在处理数据后,应用程序几乎立即变得非常缓慢且无响应。这就是我目前尝试处理的方式:

   var saLines = textBox1.Lines;
   var saNewLines = saLines.Skip(50);
   textBox1.Lines = saNewLines.ToArray();

此代码每 100 毫秒从计时器运行一次。有没有更好的方法来处理这个?我正在使用 Microsoft Visual C# 2008 Express Edition。谢谢。

【问题讨论】:

  • 您能发布显示信息的示例和执行此操作的代码吗?

标签: c# performance timer textbox


【解决方案1】:

简单的答案是TextBox.AppendText()

您最初会获得更好的性能。 我测试了每 20 毫秒写一条 500 字符的消息,持续 2 分钟(使用 BackgroundWorker),并且 UI 保持响应和 CPU 最小化。当然,在某些时候,它会变得无响应,但它足以满足我的需求。

【讨论】:

  • 谢谢。几个月后,我能够通过在 backgroundWorker 中构建全局 StringBuilder 对象,然后在 backgroundWorkerReportProgressbackgroundWorkerRunWorkerCompleted 方法中使用 TextBox.AppendText() 来完成这项工作。
  • 不敢相信我不知道这个!我知道通过其他方法一定会更慢,但速度提升很棒!并且文本框实际保持响应。
【解决方案2】:

尝试在内存中创建一个包含内容的列表,并通过 RemoveRange 删除前 50 个元素,然后使用 ToArray(); 像这样:

lst.RemoveRange(0,50);
textBox1.Lines = lst.ToArray();

应该会快很多。

【讨论】:

    【解决方案3】:

    我想说你的主要问题是你使用 TextBox 作为你的文本的主要存储。每次调用 TextBox.Lines 时,字符串都会在 Environment.NewLine 上拆分。

    试着扭转局面:

    • 将文本存储在new List<String>(maxLines)
    • 在您的 AddLine 方法中,检查文本缓冲区的长度并使用 RemoveRange(0, excessCount)
    • 通过调用String.Join(Environment.NewLine, textBuffer.ToArray()) 更新您的显示文本框

    最后一个电话有点贵,但它应该可以阻止你的减速。为了更快地获得它,您需要使用静态大小的字符串数组并在自己周围移动引用。

    【讨论】:

      【解决方案4】:

      修剪数组的最有效方法是创建所需大小的新数组,然后使用Array.Copy 复制旧数组的所需部分。


      我建议您维护一个包含所有行的List<string>。 您应该使用StringBuilder 来构建一个包含您要查找的行的字符串,并将文本框的Text proeprty 设置为StringBuilder 的字符串。为了提高性能,请将 StringBuilder 的容量设置为对字符串最终 sie 的合理猜测。 (或list.Skip(...).Take(...).Sum(s => s.Length)

      如果您担心内存问题,可以通过调用RemoveRange 来修剪List<string>

      只要您不要一次在文本框中输入太多内容,这样做应该非常快。 List<string>StringBuilder 的所有操作都可以在后台线程中完成,您可以将完成的字符串传递给 UI 线程。

      TextBox.Lines 属性只是将您使用 StringBuilder 提供给它的数组连接起来,因此使用它(并制作一个不必要的数组)毫无意义。

      【讨论】:

        【解决方案5】:

        不要拆分文本然后重新加入它,只需从第 51 行获取子字符串:

        int i = textBox1.GetFirstCharIndexFromLine(50);
        if (i > 0) textBox1.Text = textBox1.Text.Substring(i);
        

        【讨论】:

          猜你喜欢
          • 2019-03-28
          • 2018-09-03
          • 1970-01-01
          • 2021-12-24
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多