問題很簡單:我需要在處理耗時計算時更新WPF應用程序的進度。在我的嘗試中,我做了一些Google搜索,最後基於這個解決方案的第一個代碼片段:How to update UI from another thread running in another class。這裏是我的代碼:C#WPF應用程序執行任務的更新進度
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using System.Threading;
namespace ThreadTest
{
public class WorkerClass
{
public int currentIteration;
public int maxIterations = 100;
public event EventHandler ProgressUpdate;
public void Process()
{
this.currentIteration = 0;
while (currentIteration < maxIterations)
{
if (ProgressUpdate != null)
ProgressUpdate(this, new EventArgs());
currentIteration++;
Thread.Sleep(100); // some time-consuming activity takes place here
}
}
}
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
}
private void btnStart_Click(object sender, RoutedEventArgs e)
{
WorkerClass wItem = new WorkerClass();
wItem.ProgressUpdate += (s, eArg) => {
Dispatcher.BeginInvoke((Action)delegate() { txtProgress.Text = wItem.currentIteration.ToString(); });
};
Thread thr = new Thread(new ThreadStart(wItem.Process));
thr.Start();
// MessageBox.Show("Job started...");
while (thr.IsAlive == true)
{
Thread.Sleep(50);
}
MessageBox.Show("Job is done!");
}
}
}
的問題是,如果我用Dispatcher.Invoke
,比工作線程(THR)進入WaitSleepJoin狀態的第一個週期傳球后並沒有恢復,因此整個應用程序凍結。我已經使用了幾個建議來代替使用Dispatcher.BeginInvoke
,但在這種情況下,進度不會更新,直到過程完成工作。我想這個問題與切換線程有關,但不能得到確切的點。
可能重複[如何從另一個線程更新UI](http://stackoverflow.com/questions/9602567/)。 –
@DourHighArch:這個問題清楚地表明OP已經理解如何使用Dispatcher.Invoke()。他有一個不同的(雖然常見)問題。這個問題不是你建議的副本的重複。它可能是其他問題的重複,但我確實看過並找不到一個用於WPF的文件(Winforms有一個數字),並且以易於理解的方式直接解決了這個問題。 –
@DourHighArch,是的。我看到了該線程,並根據解決方案回覆的第一個片段編寫了我的代碼。正如Peter Duniho所說,這個問題更多的是爲什麼它可能不起作用。我在這個問題上花了兩天沒有結果,需要某種地方挖掘。 – Vasiliy