我正在尝试查找/开发一种非常轻量级的方法,以便在桌面应用程序的窗格中显示文本。除了为所有文本设置单一字体外,我没有文本格式的要求。我尝试过使用TextBox,TextBlock和各种可观察的集合。计算效率至关重要。
文本由应用程序创建,永远不会被用户修改。最重要的要求是应用程序通常以每秒100到700行的速度生成文本,峰值速率为每秒1900行。应用程序运行几天并不罕见。理想情况下,显示将连续滚动,以便最后添加的行始终可见。
我当前的实现使用TextBox(对于更长的时间段,我目前别无选择,只能禁用文本显示)。我尝试过的事情包括:
我可以提供有关我尝试过的更多细节,但我不想从写一本书开始。
这是我目前的XAML实施:
<TextBox Grid.Row="1" Name="tbTraceLog" IsReadOnly="True" IsUndoEnabled="False" VerticalScrollBarVisibility="Auto" FontFamily="Courier New"/>
在代码隐藏中:
for (icount = 0; icount < tlData.stringcount; icount++)
{
tbTraceLog.AppendText(tlData.s[icount]); // TextBox implementation
if (tbTraceLog.LineCount > 1000)
{
// Remove one line
tbTraceLog.Text = tbTraceLog.Text.Substring(tbTraceLog.Text.IndexOf('\n')+1);
}
}
tbTraceLog.ScrollToEnd();
我可以开始使用更基本的文本渲染类吗? TextBlock / TextBox继承了哪些类?
答案 0 :(得分:0)
我不相信控件选择是问题,我相信你的问题是与维护字符串连接相关的性能。我假设,因为您尝试删除第一个条目以在1000之后添加新条目,因此您不需要保留历史记录。也不需要处理每1秒产生的最大1900条消息。
我会将TextBox作为您的控件。使它成为多行和只读。
为结果创建一个类级别列表:
List<string> list = new List<string>();
创建公共字符串属性:
public string Result
{
get
{
return string.Concat(list);
}
}
在您的XAML中,将TextBox.Text绑定到Result属性:
<TextBox Text="{Binding Path=Result}" />
接下来创建一个名为update的类级别布尔值:
private bool update = false;
当您收到要连接的结果时,请检查list.Count&gt; 1000.如果是,则列出.RemoveAt(0)然后list.Add(newTextToAdd + Environment.NewLine)。然后将update设置为true。请注意我假设您收到一次添加一个文本。如果您收到了一组文本,则可以计算要删除的文本数量,然后调用list.AddRange(collection)。
if (list.Count > 1000)
{
list.RemoveAt(0);
list.Add(newTextToAdd + Environment.NewLine);
}
update = true;
创建一个计时器。我会说它设置为1秒钟。然后,当它触发检查我们是否更新了我们的列表。如果是,则提高Result属性更改通知,然后将update设置为false:
if (update)
{
OnPropertyChanged("Result");
update = false;
}
应该这样做。我认为string.Concat应该足够快,以便在1秒计时器上有你的负载。我认为使用计时器是可以接受的,因为应用程序每秒生成X条消息。排队到列表也应该没问题,因为如果文本在一秒钟内生成超过1000个,那么它只会错过查看文本。由于您已经尝试将最大值限制为1000,因此似乎不需要支持更多。