我认为这可能是以前被问过的,但我可能太愚蠢,无法理解给出的答案,所以我需要再次提问。使用来自线程的消息更新用户界面
我有一个类对某些数据进行计算。在计算过程中,我希望通过数据检查,状态更新和数据线向UI输出错误通知。我想实时做到这一点。从主应用程序中调用此函数时遇到的问题是,UI(在WPF中)冻结,直到所有计算完成,然后一次显示所有消息。对于需要20到30秒完成的计算来说,这是有问题的。
所以我想使用线程。这几乎是我第一次尝试这种东西。我做的是这样的:
private void btnStartCalculations_Click(object sender, RoutedEventArgs e)
{
//initialise parameters for run
calculator = new Calculator(...);
//Subscribe to calculator events for update
kasenCalculator.OnStatusUpdate += new Calculator.UpdateEventHandler(calculator_OnStatusUpdate);
//kasenCalculator.OnErrorLogUpdate += new Calculator.ErrorLogUpdateEventhandler(calculator_OnErrorLogUpdate);
//kasenCalculator.OnDataReadUpdate += new Calculator.DataReadUpdateEventHandler(calculator_OnDataReadUpdate);
//Run
Thread thread = new Thread(calculator.Run);
thread.Start();
}
private void calculator_OnStatusUpdate(object sender, string Message)
{
Dispatcher.Invoke(DispatcherPriority.Normal, new Action<string>(UpdateStatusWindow), Message);
}
private void calculator_OnDataReadUpdate(object sender, string Message)
{
Dispatcher.Invoke(DispatcherPriority.Normal, new Action<string>(UpdateOriginalDataWindow), Message);
}
private void calculator_OnErrorLogUpdate(object sender, string Message)
{
Dispatcher.Invoke(DispatcherPriority.Normal, new Action<string>(UpdateErrorLog), Message);
}
private void UpdateStatusWindow(string Message)
{
TextBox statusWindow = this.txtStatus;
//Add status text
statusWindow.Text += Message + "\r\n";
//Scroll to bottom of window
statusWindow.CaretIndex = statusWindow.Text.Length;
statusWindow.ScrollToEnd();
}
private void UpdateOriginalDataWindow(string Message)
{
this.txtOriginalData.Text += Message;
}
private void UpdateErrorLog(string Message)
{
this.txtErrors.Text += Message + "\r\n";
}
哪种类型的作品,该UI 是得到更新,但它仍然不是非常敏感。我想知道是否应该使用BeginInvoke
而不是Invoke
,但是它只是保留所有的更新,直到计算完成并且我还可以在主线程中执行。
此外,即使这是运行,它实际上运行比我预期的要慢很多。
这是正确的方式去做我想做的事吗?如果不是,那么正确的方法是什么?
感谢您使用ItemsControl的提示,这比添加到文本框要好得多。至于BeginInvoke ...当我用它替换Invoke时,我的UI不再刷新,我不明白为什么......它在等待什么?有没有办法强制处理所有未完成的任务? – 2012-02-06 02:57:15
对不起,我对此没有任何进一步的了解。我无法想象为什么它不会更新给定的变化。 – 2012-02-07 15:02:32
希望你不介意这个(很晚),但我很好奇你最终做了什么?另外,'calculator_OnStatusUpdate'在工作线程上执行,所以在我看来,'Dispatcher'属于那个线程而不是UI线程。 (注意:我没有使用WPF。)指定正确的一种方法是:'this.Dispatcher.BeginInvoke(...)'。 – groverboy 2013-02-07 02:27:26