C# 后台线程编程 - BackgroundWorker
用途
Win Form程序不做特别操作是在GUI线程运行的,如果你有比较耗时的工作,将会Hold住GUI没法更新显示运行状态。
BackgroundWorker 类是你能够另起一个线程,将线程进度汇报给GUI线程,也可以从GUI线程通知这个线程终止。
技术解释
-
WinForm开发界面时,从Toolbox选择BackgroundWorker加到Form。并修改名称(属性》Name)。在这个范例里面我改名字为backgroundWorkerCounter,因为我要让它做一个倒计数。
-
在其属性设置支持WorkerReportProgress和WorkerSupportsCancellation
-
在backgroundWorker属性》事件》Asynchronous》下面3个事件的空白处双击,创建空白的事件响应方法。
-
编程
a. 如下图所示,后台线程的主线工作在bdw_DoWork()里面完成。这个方法里面定义了你的工作、对终止后台工作的响应,并且调用ReportProgress()方法向GUI线程报告进度。
b. 在GUI线程你可以对实例化的bgw如此操作:
RunWorkerAsync(): 启动一个异步线程,不会Hold住界面。如果要向后台程序传递参数,可以在方法调用里面加数据,在后台调用e.Argument获取。详见例程。
CancelAsync(): 通知后台线程终止,实际上就是传递一个布尔标记。
c. 在GUI线程你可以对后台事件如此响应:
bgw_ProgressChanged(): 响应后台ReportProgress进度值变化
bgw_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.Tasks;
using System.Windows.Forms;
using System.Threading;
/// <summary>
/// 显示一个计数的范例,演示Background Worker的编程
/// </summary>
namespace bgwCounter
{
public partial class Form1 : Form
{
/// <summary>
/// 自动生成的Form实例化
/// </summary>
public Form1()
{
InitializeComponent();
}
/// <summary>
/// BackgroundWorker主要工作在此,方法框架是VS自动生成的
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void backgroundWorkerCounter_DoWork(object sender, DoWorkEventArgs e)
{
//从输入变量获得计数起始值
int counterStart = (int) e.Argument;
int counter = 0;
//循环递减到0
for (int i = 0; i < counterStart+1; i++)
{
counter = counterStart - i;
//如果倒计数过程中软件调用了backgroundWorker Cancel,则退出循环
if(backgroundWorkerCounter.CancellationPending==true)
{
e.Cancel = true;
break;
}
//每次循环等待1秒
Thread.Sleep(1000);
//每次循环汇报进度,此处为倒计数值,供显示
backgroundWorkerCounter.ReportProgress(counter);
}
}
/// <summary>
/// backgroundWorker进度更新调用函数,用来显示倒计数值
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void backgroundWorkerCounter_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
//本方法在GUI线程,更新文本显示的计数值
textBoxCounter.Text = e.ProgressPercentage.ToString();
}
/// <summary>
/// backgroundWorker完成后的扫尾工作
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void backgroundWorkerCounter_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
if(e.Cancelled==true)
{
//如果因为取消而完成,显示相应信息
labelMessage.Text = "counter cancelled by user";
}
else
{
//否则,即为正常完成倒计数
labelMessage.Text = "count down completed";
}
}
/// <summary>
/// Form中点击Start按钮触发此方法,启动backgroundWorker
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void buttonStart_Click(object sender, EventArgs e)
{
backgroundWorkerCounter.RunWorkerAsync((int) numericUpDownCounterStart.Value);
}
/// <summary>
/// For中Stop按钮触发此方法,向backgroundWorker发出取消执行事件
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void buttonStop_Click(object sender, EventArgs e)
{
backgroundWorkerCounter.CancelAsync();
}
}
}
总结
写到这里也结束了,在文章最后放上一个小小的福利,以下为小编自己在学习过程中整理出的一个关于 java开发 的学习思路及方向。从事互联网开发,最主要的是要学好技术,而学习技术是一条慢长而艰苦的道路,不能靠一时激情,也不是熬几天几夜就能学好的,必须养成平时努力学习的习惯,更加需要准确的学习方向达到有效的学习效果。
由于内容较多就只放上一个大概的大纲,需要更及详细的学习思维导图的 点击我的Gitee获取。
还有 高级java全套视频教程 java进阶架构师 视频+资料+代码+面试题!
全方面的java进阶实践技术资料,并且还有技术大牛一起讨论交流解决问题。