我正在开发一个简单的串行数据查看器,用于观察传输到计算机串行端口之一的数据。我用C#和WPF写了一个测试应用程序;它只是将最近读取的行放入文本块中。但是,它会跳过其他所有行。我的理论是,在WPF呈现窗口之前,新数据被放入文本块中。但是,我已经尝试了我能想到的每个线程优先级的组合,并且最多,应用程序显示其他每一行;在最坏的情况下,它显示每20行。
我在多核计算机上运行。我的应用程序包含一个文本块和一个用于打开/关闭端口的按钮。 (我尝试用文本框替换文本块,我观察到同样的问题)
我的 DataReceived 处理程序:
private void MainWindow_DataReceived(object sender, System.IO.Ports.SerialDataReceivedEventArgs e)
{
string message = sp.ReadLine();
if (string.IsNullOrWhiteSpace(message))
return;
this.Dispatcher.BeginInvoke(DispatcherPriority.Send, (ThreadStart)delegate()
{
text.Text = message;
this.InvalidateVisual();
});
}
此应用程序的最高优先级是处理大量数据的持续吞吐量; WPF适合这种情况吗?如果是的话,我做错了什么?
答案 0 :(得分:3)
我的一家公司产品正在显示来自服务器的“近乎实时”的数据更新,您可以尝试以下几种方法....
如果您对其进行数据绑定而不是直接设置,则可以将text.Text移到调度程序调用之外。
你可以这样做:
添加依赖项属性:
public static readonly DependencyProperty MessageTextProperty =
DependencyProperty.Register("MessageText", typeof(string), typeof(MyWidowClass),
new UIPropertyMetadata(string.Empty));
public string MessageText
{
get { return (int)GetValue(MessageTextProperty ); }
set { SetValue(MessageTextProperty , value); }
}
你的xaml文本框上的:
<TextBox Text="{Binding Path=MessageText, ElementName=xNameOfMyWindow}"/>
其中xNameOfMyWindow是窗口标记的x:Name属性
现在你的代码会喜欢这个:
private void MainWindow_DataReceived(object sender, System.IO.Ports.SerialDataReceivedEventArgs e)
{
string message = sp.ReadLine();
if (string.IsNullOrWhiteSpace(message))
return;
this.MessageText = message;
}
答案 1 :(得分:2)
我意识到这里游戏已经很晚了,但是在这个问题挣扎了大约一个月之后,我偶然发现了我的问题来源:文本框更新缓慢:
关闭textwrapping完全删除了我的UI锁定问题:
TextWrapping = “NoWrap的”
当然,这意味着您需要更加负责确保在通过Environment.NewLine更新文本框之前正确包装字符串,但我认为这是一个很小的代价。
希望这有帮助。
答案 2 :(得分:0)
我有点晚了,但我遇到了这个问题。 我发现 SpellCheck 属性似乎减慢了 WPF 文本框中的文本输入速度。由于我需要拼写检查,我解决了这个问题,添加了一个简单的 Forms.Timer:当用户开始写作时,文本框的 textchanged 事件禁用拼写检查并启动计时器。然后,当一秒过去时,计时器的滴答事件启用拼写检查。 现在文本框应该是快速的。 希望这可以帮助解决这个令人沮丧的问题的人。