WPF的进度条与多线程

您所在的位置:网站首页 kaggle上传数据进度条不动 WPF的进度条与多线程

WPF的进度条与多线程

2024-01-05 17:32| 来源: 网络整理| 查看: 265

WPF的进度条与多线程

本文将用一个进度条控件作为例子来介绍WPF的多线程,进度条的例子可以较全面的让我们认识WPF多线程的特点。

当用户在我们的应用程序下载东西或者加载大量数据的时候,不可避免需要用户等待一段较长的时间,这时候,我们需要一个进度条来实时反映进度给用户,避免用户以为程序死机而进行的一系列蜜汁操作。 那么,先让我们上一个进度条吧。

XAML代码:

进度条画面 有多种方法可以控制进度条的进度,但本文中主要介绍具有代表性的4种。用来介绍如何在WPF中使用多线程。

一、单线程(失败)

后台代码:

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