我正在写一个很多很多格式化文本的日志到.net窗体窗体应用程序中的文本框。向文本框写入大量文本
一旦数据超过了几个兆位,速度就会变慢。由于我追加字符串必须重新分配每一次?我只需要将该值设置为文本框一次,但在我的代码中,我做了数万次的line+=data
。
有一个更快的方法来做到这一点?也许是不同的控制?有我可以使用的链接列表字符串类型吗?
我正在写一个很多很多格式化文本的日志到.net窗体窗体应用程序中的文本框。向文本框写入大量文本
一旦数据超过了几个兆位,速度就会变慢。由于我追加字符串必须重新分配每一次?我只需要将该值设置为文本框一次,但在我的代码中,我做了数万次的line+=data
。
有一个更快的方法来做到这一点?也许是不同的控制?有我可以使用的链接列表字符串类型吗?
如果文本框是逐步添加的,比如日志输出,StringBuilder将不起作用。
但是,如果上述属实,如果你的更新不够频繁,可能理应你缓存更新的一些数字,然后在一个步骤追加他们(而不是不断追加)。这会为你节省很多字符串重新分配,然后StringBuilder会有帮助。
注:
虽然你的答案是绝对相关的,但我认为声明*我只需要将该值设置为文本框一次,但在我的代码中,我正在执行line + = data数万次。*表示它不会是回答他的具体问题。 – Marc 2010-08-06 21:09:34
@马克:事实上,保罗的答案非常好。一个线程锁定SB,附加到它,解锁。它做了很多次。 UI线程可以每秒轮询一些次数,锁定SB,获取ToString并清除它。这样,UI更新频率完全独立于级联频率。 – 2010-08-06 21:23:38
还没有人提到虚拟化,这实际上是为海量数据提供可预测性能的唯一途径。即使使用StringBuilder
并将其转换为每半秒一个字符串将是非常一旦日志变得足够缓慢。通过数据虚拟化,您只需要在内存中保存必要的数据(即用户可以看到的内容,或者在任何一边可能会看到更多内容),而其余内容则会存储在磁盘上。随着新数据的出现,旧数据会“滚出”内存。
为了使TextBox
出现好像它有很多在它的数据,你会告诉它一样。当用户滚动时,您可以使用来自底层源的相关数据(使用随机文件访问)替换缓冲区中的数据。所以你的UI将监视一个文件,而不是监听日志事件。
当然,这比单纯使用StringBuilder
的工作要多得多,但我认为这值得一提,以防万一。
如果你仔细看看Paul Sasik的回答,包括我的评论,我想你会发现它不会因大字符串而减慢。这是因为我们在写入TextBox时仍然使用AppendText并继续清理StringBuilder。 – 2010-08-07 12:49:41
@Steven:但是'TextBox'仍然包含所有数据,因此您的数据可以获得的大小仍然受到限制。虚拟化消除了这种情况,因为它只是查看整个数据集的一个小窗口。你只受到磁盘空间的限制。 – 2010-08-07 15:03:16
任何成本/收益分析必须包含成本。虚拟化的文本框不太有用,因为你甚至不能做简单的事情,比如Ctrl + A,Ctrl + C。虚拟化适用于连接到数据库表的网格等情况。 – 2010-08-07 15:09:04
为什么你不使用StringBuilder,而你正在连接,并且一旦你完成设置ToString到TextBox.Text? – 2010-08-06 20:40:32
@Alfred:对你的建议看起来很小的变化是最有效的。其不同之处在于StringBuilder将用于累积文本,然后使用AppendText()将文本附加到TextBox,之后清除StringBuilder。 – 2010-08-07 15:10:38