当前,我的应用程序有一个文本框,它将在屏幕上显示500行实时日志记录。由于应用程序后面有很多繁重的任务,因此我会尽我所能为我的应用程序改进这一部分。打开任何建议。谢谢。
WPF:
<TextBox Text="{Binding StatusMessage}" TextWrapping="Wrap" AcceptsReturn="True" />
方法1:
private void OutputMessage(string msg)
{
//Result
//1000 Lines 108ms
//10000 Lines 1687ms
if(!string.IsNullOrEmpty(msg))
{
string msgWithTimeStamp = System.DateTime.Now.ToString() + ": \t" + msg;
int msgLine = 0;
if (!string.IsNullOrEmpty(StatusMessage))
{
//Only show 500 lines of latest messages...
msgLine = StatusMessage.Count(m => m == '\n');
if (msgLine > 500)
StatusMessage = StatusMessage.Remove(0, StatusMessage.IndexOf("\n") + 1);
StatusMessage = StatusMessage + "\n" + msgWithTimeStamp;
}
else
StatusMessage = msgWithTimeStamp;
}
}
方法2(效果更好):
List<string> msgList;
private void OutputMessage(string msg)
{
//Result
//1000 Lines 31ms
//10000 Lines 377ms
if (!string.IsNullOrEmpty(msg))
{
string msgWithTimeStamp = System.DateTime.Now.ToString() + ": \t" + msg;
msgList.Add(msgWithTimeStamp);
if (msgList.Count > 500)
msgList.RemoveAt(0);
StatusMessage = String.Join("\n", msgList);
}
}
答案 0 :(得分:4)
代替使用TextBox,可以使用ItemsControl,并将数据的ItemsSource绑定到ObservableCollection。然后,您只需将每条新消息附加到ObservableCollection,ItemsControl就会自动更新,以在列表的末尾显示新条目。
答案 1 :(得分:3)
最大的问题是以下几行:
StatusMessage = String.Join("\n", msgList);
这意味着您在每次更新主字符串列表时都将重建整个字符串,并循环遍历整个列表,分配新的内存缓冲区,直到缓冲区足够大以填充整个字符串(所有500行)为止。当您的消息列表增加到500行时,这意味着下一条消息将导致500个缓冲区分配,仅用于重建完整的字符串。
一种更好的方法是在邮件列表旁边(在StringBuilder
变量中)维护一个msgList
。 StringBuilder
擅长在您修改邮件时分配缓冲区。
我写了以下代码段,在我的机器上,将新消息添加到列表中已经有500条消息的时间不到一毫秒。
// Somewhere in your code, probably next to your [msgList] variable...
private StringBuilder sb = new StringBuilder();
private void OutputMessage(string msg)
{
if (!string.IsNullOrEmpty(msg))
{
string msgWithTimeStamp = System.DateTime.Now.ToString() + ": \t" + msg;
msgList.Add(msgWithTimeStamp);
sb.AppendLine(msgWithTimeStamp);
if (msgList.Count > 500)
{
sb.Remove(0, msgList[0].Length + 2); // The +2 is to account for the new line and carriage return characters.
msgList.RemoveAt(0);
}
statusMessage = sb.ToString();
}
}
此方法的唯一缺点是两次维护同一组消息。