异步编程中async/await特性:适合需要在后台完成的与主线程不相关的小任务,不需要向主线程汇报进度
BackgroundWorker类:适合需要另建一个线程,在后台持续运行以完成某项工作,并不时地与主线程通信。
BackgroundWorker类的使用:主要是通过设置BackgroundWorker类的属性,调用三个方法触发事件,以及通过三个事件中的第二个参数EventArgs类的子类传递信息,整个过程形成一个闭环。
注意点:
1、每调用一次ReportProgress()方法会触发一次ProgressChanged_Handler事件处理程序,向主线程汇报后台线程的进度,并执行ProgressChanged_Handler事件中的内容。
2、当调用CancelAsync()方法,发出取消后台线程的命令,CancellationPending属性会设置为True,DoWork_Handler事件中的程序检测到CancellationPending为True后,程序并不会马上退出DoWork_Handler事件,必须执行完DoWork_Handler事件中的内容程序才会退出,DoWork_Handler事件不会自动马上退出的,即使接收到取消后台线程命令,它只可以改变接下来DoWork_Handler事件中程序执行的内容。
3、当执行完DoWork_Handler事件中的内容后,会自动触发RunWorkerCompleted事件,并执行其中的内容。
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace WindowsFormsApplication1
{
public partial class Form1 : Form
{
BackgroundWorker bgworker = new BackgroundWorker();
int j;
public Form1()
{
InitializeComponent();
//1.设置BackgroundWorker类的属性
bgworker.WorkerReportsProgress = true; //可以向主线程报告进度
bgworker.WorkerSupportsCancellation = true; //支持异步取消
//2.事件注册,共三个事件
bgworker.DoWork += DoWork_Handler;
bgworker.ProgressChanged += ProgressChanged_Handler;
bgworker.RunWorkerCompleted +=RunWorkerCompleted;
}
private void btnprocess_Click(object sender, EventArgs e)
{
if (!bgworker.IsBusy)
{
bgworker.RunWorkerAsync(); //通过调用RunWorkerAsync方法,获取后台线程,执行DoWork_Handler事件处理程序
}
}
private void btnCancel_Click(object sender, EventArgs e)
{
bgworker.CancelAsync(); //调用CancelAsync()方法,发出取消后台线程的命令,使bgworker.CancellationPending属性设置为True,
}
private void ProgressChanged_Handler(object sender,ProgressChangedEventArgs args)
{
progressBar1.Value = args.ProgressPercentage; //args.ProgressPercentage的值等于DoWork_Handler事件中bgworker.ReportProgress(i * 10)中参数的值
}
private void DoWork_Handler(object sender, DoWorkEventArgs args) //DoWork_Handler事件包含需在后台线程执行的代码
{
//BackgroundWorker worker = sender as BackgroundWorker;
for (int i = 0; i <=10; i++)
{
//检测应用程序是否请求取消后台线程,如果请求取消后台线程则args.Cancel = true,程序并不会马上退出FOR循环,还是需要执行完FOR循环当i>10时才会退出FOR循环和DoWork_Handler事件进入到RunWorkerCompleted
//事件程序中。
if (bgworker.CancellationPending) //原程序在DoWork_Handler事件程序中另外创建了一个BackgroundWorker类worker对象,检查worker.CancellationPendin的属性,
{ //实际验证利用之前创建的bgworker对象,效果一样。
args.Cancel = true;
j = i;
}
else
{
// percentProgress:
// 已完成的后台操作所占的百分比,范围从 0% 到 100%。
bgworker.ReportProgress(i * 10); //每调用一次bgworker.ReportProgress(i*10)方法触发一次ProgressChanged_Handler事件处理程序,向主线程汇报后台线程的进度
Thread.Sleep(500);
}
}
MessageBox.Show("j={0}",j.ToString());
}
private void RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs args) //如果DoWork_Handler事件的内容执行完或会自动触发RunWorkerCompleted事件
{
progressBar1.Value = 0;
if (args.Cancelled) //异步操作停止命令是否被触发
{
MessageBox.Show("Process was cancelled","Process Cancelled");
}
else
{
MessageBox.Show("Process completed normally","Process Completed");
}
}
}
}