在一个程序中,一些耗时的操做,在长时间运行时可能会致使用户界面 (UI) 处于中止响应状态,用户在这操做期间没法进行其余的操做,为了避免使UI层处于中止响应状态,须要将这些耗时的操做,设置为后台线程,而且在UI层能够展现后台操做的进度,比较经常使用的方法有使用线程以及BackgroundWorker类。this
一、线程方法spa
当咱们要在前太展现后台的操做进程时,是不容许跨线程访问控件。此时须要取消控件的跨线程访问,在winform中能够设置CheckForIllegalCrossThreadCalls = false,而在wpf中不存在CheckForIllegalCrossThreadCalls 这个属性,在这介绍一种方法,取消跨线程访问,在wpf中有Dispatcher属性使用委托的方法来告诉控件须要作什么。线程
public Action<int> proBarDel;//先定义一个委托 /// <summary> /// 取消夸线程访问 /// </summary> /// <param name="str"></param> private void CrossThread(int i) { //取消控件夸线程访问 proBarDel = this.GetReceive; this.pb.Dispatcher.Invoke(proBarDel, i); this.lab1.Dispatcher.Invoke(proBarDel, i); } /// <summary> /// 为控件设置内容 /// </summary> /// <param name="receiveStr"></param> public void SetValue(int receive) { pb.Value = receive; lab1.Content = receive; }
//在按钮的点击事件中新增一个线程
Thread th = new Thread(() => {
for (int i = 0; i <= 100; i++)
{
CrossThread(i);//将执行的进度汇报给UI层的控件
Thread.Sleep(100);
}
});
th.IsBackground = true;
th.Start();code
当点击开始按钮时进度条就会显示进度component
二、使用BackgroundWorkerorm
BackgroundWorker 类容许在单独的专用线程上运行操做,使用BackgroundWorker 须要引用System.ComponentModelblog
BackgroundWorker 有三个重要的事件进程
this.bgWorker.DoWork += new DoWorkEventHandler(backgroundWorker_DoWork);
this.bgWorker.RunWorkerCompleted += new RunWorkerCompletedEventHandler(backgroundWorker_RunWorkerCompleted);
this.bgWorker.ProgressChanged +=new ProgressChangedEventHandler(backgroundWorker_ProgressChanged);事件
DoWork(),将须要处理的后台操做放入DoWork()中io
BackgroundWorker bgWorker = new BackgroundWorker();//建立一个BackgroundWorker
/// <summary> /// 须要处理的事件 /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void backgroundWorker_DoWork(object sender, DoWorkEventArgs e) { e.Result = DoWork(bgWorker, e); } private bool DoWork(BackgroundWorker bk,DoWorkEventArgs e) { int num = (int)e.Argument;// int p = 0; for (int i = 0; i < num; i++) { if (bk.CancellationPending)//判断是否取消后台操做 { return false; } else { p = (int)(((double)i / (double)num )* 100); bk.ReportProgress(p);//报告进度 Thread.Sleep(100); } } return true; }
ProgressChanged调用 ReportProgress 时发生
private void backgroundWorker_ProgressChanged(object sender, ProgressChangedEventArgs e) { proBar.Value = e.ProgressPercentage;//得到进度给进度条 this.lab1.Content = e.ProgressPercentage; }
RunWorkerCompleted 后台操做执行完成时或取消时发生
/// <summary> /// 处理完成 /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void backgroundWorker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e) { MessageBox.Show("ok"); }
在使用BackgroundWorker 报告后台的进度时须要将 WorkerReportsProgress 设置为true,不然在bk.ReportProgress(p)报告进度是会抛出异常
以上只是我的使用的总结,不是很全面,但愿你们补充,有错误的地方但愿可以指出
在MSDN中有对BackgroundWorker的详细的讲解https://msdn.microsoft.com/zh-cn/library/system.componentmodel.backgroundworker.aspx