本文主要是介绍BackgroundWorker应用实例,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
本文通过实例介绍BackgroundWorker组件的使用方法。使用BackgroundWorker前需要添加命名空间System.ComponentModel。本实例模拟一个耗时操作,并在操作过程中报告工作进度。这种情况使用BackgroundWorker非常合适。下面是实例程序的主画面。
下面给出程序的完整代码。
using System.ComponentModel;
using System.Threading;
using System.Windows;namespace BackgroundWorkerExp
{/// <summary>/// MainWindow.xaml 的交互逻辑/// </summary>public partial class MainWindow : Window{BackgroundWorker bw;public MainWindow(){InitializeComponent();bw = new BackgroundWorker();bw.WorkerSupportsCancellation = true;bw.WorkerReportsProgress = true;bw.DoWork += bw_DoWork;bw.ProgressChanged += bw_ProgressChanged;bw.RunWorkerCompleted += bw_RunWorkerCompleted;}private void Button_Start_Click(object sender, RoutedEventArgs e){bw.RunWorkerAsync();}void bw_DoWork(object sender, DoWorkEventArgs e){for (int i = 0; i < 100000; i++){if (i % 1000 == 0){bw.ReportProgress(i / 1000);Thread.Sleep(50);}}}void bw_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e){this.Label_CurrentProgress.Content = "操作完成";}void bw_ProgressChanged(object sender, ProgressChangedEventArgs e){this.Label_CurrentProgress.Content = e.ProgressPercentage + "%";}}
}
代码中在窗体被创建时,初始化BackgroundWorker,设置BackgroundWorker相关属性,注册BackgroundWorker相关事件,下面对代码中涉及到的属性和事件进行说明。
(1)WorkerSupportsCancellation属性:表示BackgroundWorker是否支持异步取消。当该属性设置为true时,可以调用异步方法CancelAsync来取消异步操作。
(2)WorkerReportsProgress属性:表示BackgroundWorker是否可以报告当前进度。当该属性设置为true时,可以调用ReportProgress方法来报告当前进度。
(3)DoWork事件:当调用RunWorkerAsync方法时,该事件被触发,在事件处理方法中执行耗时操作,此方法中的代码在子线程中执行,可看成使用Thread新起的一个线程。
(4)ProgressChanged事件:当调用ReportProgress方法时,该事件会被触发,在事件处理方法中可以更新画面显示当前执行进度,类似于使用BeginInvoke在子线程中刷新UI主画面的操作,这部分代码在主线程中执行。
(5)RunWorkerCompleted事件:当DoWork事件处理方法中所有代码执行完后触发该事件,该事件处理器中的代码也是在主线程中执行。
在开发中,不小心将调用RunWorkerAsync方法的代码放置在子线程的代码中。
private void Button_Start_Click(object sender, RoutedEventArgs e){Thread t = new Thread(()=>ThreadMethod());t.Start(); }void ThreadMethod(){bw.RunWorkerAsync();}
使用上面代码会在下面的代码中出现错误“调用线程无法访问此对象,因为另一个线程拥有该对象”。
void bw_ProgressChanged(object sender, ProgressChangedEventArgs e){this.Label_CurrentProgress.Content = e.ProgressPercentage + "%";}
原因极其明显,代码“this.Label_CurrentProgress.Content = e.ProgressPercentage + "%";”只有在主线程中执行才能正常工作,因为Label_CurrentProgres的拥有者是主线程而不是某个子线程,在子线程直接操作UI主线程中的对象是不允许的。
这篇关于BackgroundWorker应用实例的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!