更新具有大量文本的多行文本框的最快方法

本文关键字:文本 方法 更新 | 更新日期: 2023-09-27 18:35:24

我有一个.NET 4.5 WinForm程序,它使用ODBC查询基于文本的数据库。然后,我想在多行文本框中显示每个结果,并且我想以最快的方式完成。
在更新/填充文本框期间,GUI 不必可用。但是,如果我能更新进度条以让用户知道正在发生的事情,那就太好了 - 我相信后台工作者或新线程/任务是必要的,但我从未实现过。

我最初使用这段代码,它很慢,因为它在继续下一行之前每行都绘制出结果。

OdbcDataReader dbReader = com.ExecuteReader();
while (dbReader.Read())
{
   txtDatabaseResults.AppendText(dbReader[0].ToString());
}

这要快得多。

string resultString = "";
while (dbReader.Read())
{
   resultString += dbReader[0].ToString();
}
txtDatabaseResults.Text = resultString;

但是在文本框复活之前有一个很长的等待时间,所以我想知道操作是否可以更快。现在我正在从文件中获取大约 7,000 行,我认为没有必要切换到 AvalonEdit(如果我的思维方式是错误的,请纠正我,但我想保持简单并使用内置文本框)。

更新具有大量文本的多行文本框的最快方法

您可以通过使用

StringBuilder 而不是使用字符串连接来加快此操作速度。

var results = new StringBuilder();
while (dbReader.Read())
{
    results.Append(dbReader[0].ToString());
}
txtDatabaseResults.Text = results.ToString();

使用string和串联会给 GC 带来很大的压力,尤其是在追加 7000 行文本时。 每次使用 string += 时,CLR 都会创建一个新的字符串实例,这意味着需要对较旧的字符串实例(逐渐变大)进行垃圾回收。 StringBuilder避免了这个问题。

请注意,将文本分配给TextBox时仍会存在延迟,因为它需要刷新并显示该文本。 TextBox控件未针对该文本量进行优化,因此这可能是一个瓶颈。

至于将其推送到后台线程 - 由于您使用的是 .NET 4.5,因此您可以使用新的异步支持来处理此问题。 这将通过将包含此代码的方法标记为async,并使用如下代码来工作:

string resultString = await Task.Run(()=>
{
    var results = new StringBuilder();
    while (dbReader.Read())
    {
        results.Append(dbReader[0].ToString());
    }
    return results.ToString();
});
txtDatabaseResults.Text = resultString;

使用 StringBuilder:

StringBuilder e = new StringBuilder();
while (dbReader.Read())
{
   e.Append(dbReader[0].ToString());
}
txtDatabaseResults.Text = e.ToString();

尽管建议使用并行Thread,但从文件中提取行的方式存在某种缺陷。虽然每次连接string时都是不可变的resulString但实际上您创建了另一个(更大的)字符串。在这里,StringBuilder非常有用:

StringBuilder resultString = new StringBuilder ()
while (dbReader.Read())
{
   resultString = resultString.Append(dbReader[0].ToString());
}
txtDatabaseResults.Text = resultString;

我在一次调用中用一个很长的字符串(超过 200kB,从文件加载)填充一个常规文本框(多行 = true)。我只是用我的字符串分配文本框的 Text 属性)。它非常慢(> 1 秒)。文本框除了显示巨大的字符串外,还会执行任何其他操作。

使用了一个非常简单的技巧来提高性能:我用RichTextBox(本机控件)替换了多行文本框。

现在,相同的加载是即时的,RichTextBox具有与原始文本的TextBox完全相同的外观和行为(只要您没有调整它)。最明显的区别是RTB默认情况下没有上下文菜单。

当然,它

并不是每种情况下的解决方案,也不是针对 OP 问题,但对我来说它工作得很好,所以我希望它可以帮助其他面临相同问题的人在 Textbox 和大字符串的性能方面遇到同样的问题。