BackgroundWorker组件介绍
BackgroundWorker是·net里用来执行多线程任务的控件,它允许编程者在一个单独的线程上执行一些操作。
常用方法
- RunWorkerAsync 开始执行后台操作。引发 DoWork 事件
- CancelAsync 请求取消挂起的后台操作。注意:这个方法是将 CancellationPending 属性设置为 true,并不会终止后台操作。在后台操作中要检查CancellationPending 属性,来决定是否要继续执行耗时的操作。
- ReportProgress引发 ProgressChanged 事件。
常用属性
- CancellationPending 指示应用程序是否已请求取消后台操作。只读属性,默认为 false,当执行了 CancelAsync 方法后,值为 true。
- WorkerSupportsCancellation指示是否支持异步取消。要执行 CancelAsync 方法,需要先设置该属性为 true。
- WorkerReportsProgress指示是否能报告进度。要执行 ReportProgress 方法,需要先设置该属性为 true。
注意: - 在 DoWork 事件处理程序中不操作任何用户界面对象。而应该通过 ProgressChanged 和RunWorkerCompleted 事件与用户界面进行通信。
- 如果想在 DoWork 事件处理程序中和用户界面的控件通信,可在用 ReportProgress 方法。ReportProgress(int percentProgress, object userState),可以传递一个对象。ProgressChanged 事件可以从参数ProgressChangedEventArgs 类的UserState 属性得到这个信息对象。这个事件也可以实现进度条功能,把任务的进度实时呈现给用户。
- 简单的程序用BackgroundWorker 比 Thread 方便,Thread中和用户界面上的控件通信比较麻烦,需要用委托来调用控件的 Invoke 或BeginInvoke 方法,没有 BackgroundWorker 方便。
实例
public partial class Analyse : Form
{
public Analyse()
{
InitializeComponent();
CheckForIllegalCrossThreadCalls = false; //线程间操作无效: 从不是创建控件“XXX”的线程访问它。
}
/// <summary>
/// Analyse
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void Analyse_btn_Click(object sender, EventArgs e)
{
try
{
// 数据分析
if (!bgWorker_Process.IsBusy)
{
AnalyseResults = new List<AnalyseResultMdl>();
this.bgWorker_Process = new BackgroundWorker() //new一个新的,避免重复添加相同和其他无用DoWork,也可以不用new
{
WorkerReportsProgress = true //能否报告进度更新
};
this.bgWorker_Process.DoWork += new DoWorkEventHandler(Analyse_DoWork);
this.bgWorker_Process.ProgressChanged += new ProgressChangedEventHandler(bgWorker_Process_ProgressChanged);
this.bgWorker_Process.RunWorkerCompleted += new RunWorkerCompletedEventHandler(bgWorker_Process_RunWorkerCompleted);
this.bgWorker_Process.RunWorkerAsync(); // 运行 backgroundWorker 组件
}
else
{
MessageBox.Show($"等待其他操作完成再执行...");
}
}
catch (Exception ex)
{
MessageBox.Show($"分析出错:{ex}");
}
}
/// <summary>
/// Analyse_DoWork
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void Analyse_DoWork(object sender, EventArgs e)
{
int intPercentage=1;
foreach (var item in itemList)
{
bgWorker_Process.ReportProgress(Convert.ToInt32(Math.Floor(Convert.ToDouble(intPercentage * 100 / BaseDataList.Count())))); // 触发bgWorker_Process.ProgressChanged事件
// 耗时操作
// 。。。
intPercentage++;
}
}
/// <summary>
/// 进度变化
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void bgWorker_Process_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
progressBar1.Value = e.ProgressPercentage; //progressBar1 进度条控件
}
/// <summary>
/// 程序执行完成
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void bgWorker_Process_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
if (e.Error != null)
{
MessageBox.Show(e.Error.Message);
}
else if (e.Cancelled)
{
}
else
{
this.bgWorker_Process.Dispose();
}
}
}