问题很简单:我需要在处理耗时计算时更新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