BackgroundWorker 实现多线程操作
背景介绍: 在做程序的进程中,我们极可能遇到这样的情况:当我们履行1个比较耗时的操作,即界面加载数据量略大的时,在该操作未完成之前再去操作界面,就会出现停止响应的情况,这称为界面假死状态,那1个小圆圈转呀转的,想必大家看着就头疼。固然这是1个非常影响用户体验度的地方。 怎样做出1个能够及时响应的用户界面呢?多线程操作。 引入BackgroundWorker组件: BackgroundWorker是?net里用来履行多线程任务的控件,它允许编程者在1个单独的线程上履行1些操作。 经常使用方法
注意:这个方法是将 CancellationPending 属性设置为 true,其实不会终止后台操作。在后台操作中要检查 CancellationPending 属性,来决定是不是要继续履行耗时的操作。
经常使用属性
经常使用事件
注意:在 DoWork 事件处理程序中不操作任何用户界面对象。而应当通过 ProgressChanged 和RunWorkerCompleted 事件与用户界面进行通讯。 如果想在 DoWork 事件处理程序中和用户界面的控件通讯,可在用 ReportProgress 方法。ReportProgress(int percentProgress,object userState),可以传递1个对象。 ProgressChanged 事件可以从参数ProgressChangedEventArgs 类的UserState 属性得到这个信息对象。这个事件也能够实现进度条功能,把任务的进度实时显现给用户。
简单的程序用BackgroundWorker 比 Thread 方便,Thread中和用户界面上的控件通讯比较麻烦,需要用拜托来调用控件的 Invoke 或BeginInvoke 方法,没有 BackgroundWorker 方便。
BackgroundWorker Demo namespace BackgroundWorkerTest
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
backgroundWorker1.WorkerReportsProgress = true;//报告完成进度
backgroundWorker1.WorkerSupportsCancellation = true;//允许用户终止后台线程
}
//开始按钮
private void button1_Click(object sender,EventArgs e)
{
if (!backgroundWorker1.IsBusy )//判断backgroundWorker1是不是正在运行异步操作
{
//backgroundWorker1.RunWorkerAsync();
backgroundWorker1.RunWorkerAsync(1000);//开始履行后台操作,调用DoWork事件
}
}
//DoWork事件声明要履行的耗时操作
private void backgroundWorker1_DoWork(object sender,DoWorkEventArgs e)
{
e.Result = ListNumber(backgroundWorker1,e);//运算结果保存在e.Result中
}
bool ListNumber(object sender,DoWorkEventArgs e)
{
int num=(int)e.Argument;//接收传入的参数
for (int i = 1; i <= num; i++)
{
if (backgroundWorker1.CancellationPending)//判断是不是要求了取消后台操作
{
e.Cancel=true;
return false;
}
//backgroundWorker1.ReportProgress(i * 100 / num);
backgroundWorker1.ReportProgress(i * 100 / num,i);//报告完成进度
Thread.Sleep(0);//后台线程交出时间片
}
return true;
}
private void backgroundWorker1_ProgressChanged(object sender,ProgressChangedEventArgs e)
{
//将完成进度数据传给进度条
progressBar1.Value = e.ProgressPercentage;
label1.Text = e.ProgressPercentage + "%";
//将中间计算结果在ListBox控件中显示出来
listBox1.Items.Add(e.UserState);
}
Private void backgroundWorker1_RunWorkerCompleted(object sender,RunWorkerCompletedEventArgs e)
{
if (!e.Cancelled && e.Error==null)
{
MessageBox.Show("处理完成了吗? " + e.Result);
}
else//如果取消后台线程或产生了异常
{
MessageBox.Show("处理完成了吗? false");
}
}
//取消按钮
private void button2_Click(object sender,EventArgs e)
{
if (backgroundWorker1.WorkerSupportsCancellation==true)
{
backgroundWorker1.CancelAsync();//取消后台操作
backgroundWorker1.Dispose();//释放资源
}
}
}
}
总结: 使用backgroundWorker实现多线程大致的步骤是:
总的来讲就是用backgroundWorker组件来新建1个线程,把耗时的部份放到这个线程中在后台进行处理。这样就不会影响界面的正常使用。举个通俗的例子,在我们打开1个网页的时候,先加载完的总是文字,然后图片在渐渐出现。这就是线程的利用,网页打开的时候先显现出文字,供用户阅读,然后把加载图片放到1个单独的线程中,异步的在后台履行,履行终了后把图片显现出来。 这样就避免了1打开界面就加载大量信息,而酿成的界面假死状态,大大提高了用户体验度。
线程处理这块不熟,希望大家指导。
(编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |