WPF的进度条与多线程 |
您所在的位置:网站首页 › kaggle上传数据进度条不动 › WPF的进度条与多线程 |
WPF的进度条与多线程
本文将用一个进度条控件作为例子来介绍WPF的多线程,进度条的例子可以较全面的让我们认识WPF多线程的特点。 当用户在我们的应用程序下载东西或者加载大量数据的时候,不可避免需要用户等待一段较长的时间,这时候,我们需要一个进度条来实时反映进度给用户,避免用户以为程序死机而进行的一系列蜜汁操作。 那么,先让我们上一个进度条吧。 XAML代码:
后台代码: public partial class MainWindow : Window { public MainWindow() { InitializeComponent(); } /// /// Download按钮点击事件 /// /// /// private void Download_OnClick(object sender, RoutedEventArgs e) { for (int i = 1; i public MainWindow() { InitializeComponent(); } /// /// Download按钮点击事件 /// /// /// private void Download_OnClick(object sender, RoutedEventArgs e) { Task task = new Task(TaskMethod); task.Start(); } private void TaskMethod() { for (int i = 1; i public MainWindow() { InitializeComponent(); } /// /// Download按钮点击事件 /// /// /// private void Download_OnClick(object sender, RoutedEventArgs e) { Task task = new Task(TaskMethod); task.Start(); } private void TaskMethod() { for (int i = 1; i ProgressBar.Value = i; }, DispatcherPriority.Normal); } } }获取当前程序的Dispatcher后,使用 BeginInvoke(DispatcherPriority, Delegate)执行异步方法,在异步方法中会调用委托来实现在其他线程中调用应用程序对象。 该方法有两个参数: DispatcherPriority:用于表示该线程的优先级,一般不怎么用,优先级高的先执行。 Delegate:委托,BeginInvoke()方法会将传入的方法安排为调度程序的任务。之后调度程序会执行这个方法。 使用Dispatcher当然是合适的做法,成功的实时表示进度条的进度。我们也学会了如何在线程中调用应用程序对象。 不过,以上三种方法都弱爆了。实际上,使用BackgroundWorker组件可以近乎完美的匹配进度条的功能。 四、使用BackgroundWorker实现进度条 BackgroundWorker 属性 1.WorkerReportsProgress该属性设为True时,才会触发进度更新方法。 2.WorkerSupportsCancellation该属性设为True时,才会触发取消方法。 事件 1.DoWork将需要异步执行的方法,添加进DoWork中,BackgroundWorker工作时会触发该事件。 2.ProgressChanged将进度更新时执行的方法添加进ProgressChanged中,当WorkerReportsProgress = True时,进度更新时会触发该事件。 3.RunWorkerCompleted将工作结束时的反馈方法添加进RunWorkerCompleted中,工作结束时会触发该事件。 方法 1.RunWorkerAsync(object argument)object argument:传入一个对象,使其可以在异步线程中使用。 调用该方法开始执行异步操作。 2.ProgressChanged(int percentProgress)int percentProgress:传入一个数值表示当前进度 调用该方法触发RunWorkerCompleted事件。 代码如下: 为了方便使用,可以把BackgroundWorker作为资源放进窗口的Resources里。 public partial class MainWindow : Window { private BackgroundWorker worker; public MainWindow() { InitializeComponent(); worker = (BackgroundWorker)FindResource("Worker"); } /// /// Download按钮点击事件 /// /// /// private void Download_OnClick(object sender, RoutedEventArgs e) { worker?.RunWorkerAsync(ProgressBar); } /// /// Cancel按钮点击事件 /// /// /// private void Cancel_OnClick(object sender, RoutedEventArgs e) { worker?.CancelAsync(); } /// /// 线程工作方法 /// /// /// private void Worker_OnDoWork(object sender, DoWorkEventArgs e) { for (int i = 1; i e.Cancel = true; return; } worker.ReportProgress(i); Thread.Sleep(100); } } /// /// 进度改变方法 /// /// /// private void Worker_OnProgressChanged(object sender, ProgressChangedEventArgs e) { ProgressBar.Value = e.ProgressPercentage; } /// /// 工作完成方法 /// /// /// private void Worker_OnRunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e) { if (e.Cancelled) { MessageBox.Show("已取消"); return; } MessageBox.Show("下载完成"); } }如代码所示, 1.初始化BackgroundWorker对象本例中我们在构造方法里初始化BackgroundWorker对象。 2.开始执行异步操作在Download按钮点击事件中借助BackgroundWorker的RunWorkerAsync(object argument)方法运行异步线程。 注意:Dowork中添加的方法将会在异步线程中执行。因此切记在Dowork事件中不能调用应用程序对象。 不过需要在Dowork事件中调用的对象可以作为参数传入。以实现在线程中调用。 3.实时反馈进度到窗体在Dowork事件中可以随时调用BackgroundWorker的ReportProgress(int percentProgress)方法来反馈进度到窗体。 该方法被调用时会触发Worker_OnProgressChanged()方法,实时更新窗口反馈进度给用户,因为该方法处于UI线程中,所以可以任意调用应用程序对象。 4.方法结束结果反馈DoWork事件执行结束后会触发RunWorkerCompleted事件,表示线程执行结束,在该方法中可以使用RunWorkerCompletedEventArgs参数判断线程执行状态是正常结束或者被取消等等,来决定如何更新窗体。 5.取消线程调用BackgroundWorker的CancelAsync()方法可以随时结束线程。 虽说是结束线程,但其实他并不会自动结束,而是将BackgroundWorker的CancellationPending属性设置为True,标记线程为取消状态。 开发者应在DoWork方法中自行判断CancellationPending属性来决定是否要结束线程。需要注意的是,设为取消状态后依然会触发RunWorkerCompleted事件, 需要将DoWorkEventArgs的Cancel属性设置为True,将状态传递到CancellationPending事件中,最终在结束方法里判断该属性已决定如何反馈结果到窗体。 以上,使用BackgroundWorker可以十分方便的实现进度条。当然除此之外,可以使用该类实现任何异步方法,同时反馈进度以及随时取消。 对你有帮助吗?点个赞吧~ |
今日新闻 |
推荐新闻 |
CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3 |