2010-08-06 75 views
9

我正在写一个很多很多格式化文本的日志到.net窗体窗体应用程序中的文本框。向文本框写入大量文本

一旦数据超过了几个兆位,速度就会变慢。由于我追加字符串必须重新分配每一次?我只需要将该值设置为文本框一次,但在我的代码中,我做了数万次的line+=data

有一个更快的方法来做到这一点?也许是不同的控制?有我可以使用的链接列表字符串类型吗?

+6

为什么你不使用StringBuilder,而你正在连接,并且一旦你完成设置ToString到TextBox.Text? – 2010-08-06 20:40:32

+1

@Alfred:对你的建议看起来很小的变化是最有效的。其不同之处在于StringBuilder将用于累积文本,然后使用AppendText()将文本附加到TextBox,之后清除StringBuilder。 – 2010-08-07 15:10:38

回答

7

如果文本框是逐步添加的,比如日志输出,StringBuilder将不起作用。

但是,如果上述属实,如果你的更新不够频繁,可能理应你缓存更新的一些数字,然后在一个步骤追加他们(而不是不断追加)。这会为你节省很多字符串重新分配,然后StringBuilder会有帮助。

注:

  1. 创建一个类范围的StringBuilder成员(_sb)
  2. 启动一个定时器(或使用计数器)
  3. 附加文本更新_sb
  4. 当计时器滴答声或某些计数器达到复位并追加到 文本框
  5. 从#1重启进程
+1

虽然你的答案是绝对相关的,但我认为声明*我只需要将该值设置为文本框一次,但在我的代码中,我正在执行line + = data数万次。*表示它不会是回答他的具体问题。 – Marc 2010-08-06 21:09:34

+2

@马克:事实上,保罗的答案非常好。一个线程锁定SB,附加到它,解锁。它做了很多次。 UI线程可以每秒轮询一些次数,锁定SB,获取ToString并清除它。这样,UI更新频率完全独立于级联频率。 – 2010-08-06 21:23:38

5

将您的字符串与StringBuilder一起构建,然后使用toString()将其转换为字符串,然后将其分配给文本框。

+2

也许StringBuffer是我从来没有听说过的类,但我认为它更可能是你的意思StringBuilder – 2010-08-06 20:41:14

+0

错误的语言,'StringBuffer'是java。 =) – Marc 2010-08-06 20:42:03

+0

是的,你是对的,我会编辑答案。 – Frank 2010-08-06 20:49:48

6

还没有人提到虚拟化,这实际上是为海量数据提供可预测性能的唯一途径。即使使用StringBuilder并将其转换为每半秒一个字符串将是非常一旦日志变得足够缓慢。通过数据虚拟化,您只需要在内存中保存必要的数据(即用户可以看到的内容,或者在任何一边可能会看到更多内容),而其余内容则会存储在磁盘上。随着新数据的出现,旧数据会“滚出”内存。

为了使TextBox出现好像它有很多在它的数据,你会告诉它一样。当用户滚动时,您可以使用来自底层源的相关数据(使用随机文件访问)替换缓冲区中的数据。所以你的UI将监视一个文件,而不是监听日志事件。

当然,这比单纯使用StringBuilder的工作要多得多,但我认为这值得一提,以防万一。

+0

如果你仔细看看Paul Sasik的回答,包括我的评论,我想你会发现它不会因大字符串而减慢。这是因为我们在写入TextBox时仍然使用AppendText并继续清理StringBuilder。 – 2010-08-07 12:49:41

+1

@Steven:但是'TextBox'仍然包含所有数据,因此您的数据可以获得的大小仍然受到限制。虚拟化消除了这种情况,因为它只是查看整个数据集的一个小窗口。你只受到磁盘空间的限制。 – 2010-08-07 15:03:16

+0

任何成本/收益分析必须包含成本。虚拟化的文本框不太有用,因为你甚至不能做简单的事情,比如Ctrl + A,Ctrl + C。虚拟化适用于连接到数据库表的网格等情况。 – 2010-08-07 15:09:04