更新具有大量文本的多行文本框的最快方法
本文关键字:文本 方法 更新 | 更新日期: 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 和大字符串的性能方面遇到同样的问题。