C# TextBox.ScrollToEnd花费的时间太长
我有一个LogTextBox类用于显示日志消息:C# TextBox.ScrollToEnd花费的时间太长,c#,wpf,.net-4.0,textbox,C#,Wpf,.net 4.0,Textbox,我有一个LogTextBox类用于显示日志消息: public class LogTextBox : TextBox { int maxMessageCount, messageCount; //number of characters for each message List<int> messageLengths; public LogTextBox(int maxMessageCount) { this.messag
public class LogTextBox : TextBox
{
int maxMessageCount, messageCount;
//number of characters for each message
List<int> messageLengths;
public LogTextBox(int maxMessageCount)
{
this.messageCount = 0;
this.maxMessageCount = maxMessageCount;
this.messageLengths = new List<int>();
IsReadOnly = true;
IsUndoEnabled = false;
}
public void Log(string message)
{
if (messageCount >= maxMessageCount)
{
Dispatcher.Invoke((Action)delegate()
{
//statement 1
string text = Text.Remove(0, messageLengths[0]);
//statement 2
Text = text + message + '\n';
//statement 3
ScrollToEnd();
});
messageLengths.RemoveAt(0);
messageLengths.Add(message.Length + 1);
}
else
{
Dispatcher.Invoke((Action)delegate()
{
AppendText(message + '\n');
ScrollToEnd();
});
messageLengths.Add(message.Length + 1);
messageCount++;
}
}
}
public class Test
{
public LogTextBox logView;
public Timer timer;
[STAThread]
public static void Main()
{
Application app = new Application();
Test test = new Test();
test.logView = new LogTextBox(200);
test.timer = new Timer(200);
test.timer.Elapsed += new ElapsedEventHandler(test.timer_Elapsed);
test.timer.Start();
app.Run(main);
}
int line = 0;
void timer_Elapsed(object sender, ElapsedEventArgs e)
{
logView.Log(GetMessage(line++));
}
private string GetMessage(int line)
{
StringBuilder builder = new StringBuilder();
for (int i = 0; i < 1000; i++)
builder.Append(line + " ");
builder.Append('\n');
return builder.ToString();
}
}
如果易于阅读是主要的文档使用场景。 然后你可以试着使用 注:本流程文档旨在优化查看和可读性。 RichText box表示对FlowDocument对象进行操作的丰富编辑控件 编辑: 如果您不希望应用程序中的搜索结果超过上万条,那么到目前为止,TextBlock控件或只读多行文本框就足够了。 TextBox类有一个AppendText方法,它应该足够快。您不必删除第一条消息
您可以考虑使用不同的文本框控件。 这是一个用于SharpDevelop的Wpf文本编辑器,完全从头开始。它被称为AvalonEdit,codeproject上有一篇好文章: 似乎他已经对大型内容进行了优化
您是否尝试过将报表2从
//statement 2
Text = text + message + '\n';
到
?
这只是一个猜测,但由于编写的语句2每次都分配一个新的字符串对象,因此垃圾收集器可能正在启动以释放旧字符串。我相信AppendText是以避免中间分配的方式实现的。 为什么不考虑使用不同的文本框控件? 您可以尝试支持文本突出显示的,您可以在这里阅读
本地WPF richtext控件似乎更快。我找到了logbox.ScrollToVerticalOffsetdouble.MaxValue;比logbox.ScrollToEnd;快1/3;。可能是因为它避免了对UpdateLayout的内部调用。FlowDocument不是从TextBoxBase派生的。有4个控件支持查看FlowDocument:FlowDocumentReader、FlowDocumentPageViewer、RichTextBox和FlowDocumentScrollViewer。只有RichTextBox源于TextBoxBase并具有ScrollToEnd方法,但我怀疑它能否提供更好的性能,因为它比TextBox控件更重。@AlpHancıoğlu:啊!,我的错!同意,FlowDocument不是从TextBoxBase继承的。更新我的答案。。谢谢如果我不必从开头删除邮件,我会这么做。这就是为什么我调用'string text=text.Remove0,messagelength[0];'在报表2之前。
//statement 2
Text = text + message + '\n';
AppendText(message);
AppendText('\n');