我認爲這可能是以前被問過的,但我可能太愚蠢,無法理解給出的答案,所以我需要再次提問。使用來自線程的消息更新用戶界面
我有一個類對某些數據進行計算。在計算過程中,我希望通過數據檢查,狀態更新和數據線向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