BackGroundWorker控件的使用

来源:互联网 发布:算法谜题 英文版 pdf 编辑:程序博客网 时间:2024/05/10 01:44

 

在我们平时的开发中,有使用需要执行有些比较耗时的任务(比如说插入10000条数据到数据库或进行一些比较常时间的IO操作),如果我们在主线程中直接执行该任务的话,可能会使整个界面处于假死状态.这对用户来说是一个很不好的体验,作为一个合格的程序员,绝对不能停留在“程序能用就行”的境界,而是应该充分考虑用户的体验以及界面的友好性,把软件做成一个精品。

 

针对由于任务比较耗时而情况,传统的做法是使用多线程进行处理。将耗时的任务在单独的线程中进行处理,在任务的执行过程中,将执行的进度通过委托调用主线程的方法,将进度在界面显示给用户(在VS2005中,出于安全考虑,在线程中无法直接操作主线程上的控件,只能通知主线程,由主线程对其控件的状态进行修改)。

 

一、BackGroundWorker介绍

VS2005中,为我们提供的BackGroundWorker就可以很好地为我们解决这方面的问题。即使你对多线程编程不熟悉,也可以很好地利用BackGroundWorker完成一些多线程才能完成的工作(其实BackGroundWorker在后台也是采用多线程进行工作的)。你可以把耗时的方法放在BackGroundWorker中的DoWork方法中执行,然后,通过ReportProgress方法来向主线程报告操作的进度。

 

二、BackGroundWorker的使用介绍

         我们先来看看一个使用BackGroundWorkerDEMO,如下图:

DEMO 实现得很简单,当点“开始执行”按钮时,该软件开始执行一个耗时的动作,然后在界面显示操作的进度。我们看看Demo的代码:



  1 public partial class Form1 : Form
  2
  3    {
  4
  5        public Form1()
  6
  7        {
  8
  9            InitializeComponent();
 10
 11        }

 12
 13 
 14
 15        /// <summary>
 16
 17        /// 模拟一个耗时的方法(让线程休眠一秒)
 18
 19        /// </summary>

 20
 21        private void GetData()
 22
 23        {
 24
 25            System.Threading.Thread.Sleep(1000);
 26
 27        }

 28
 29 
 30
 31        /// <summary>
 32
 33        /// 开始执行按钮动作
 34
 35        /// </summary>
 36
 37        /// <param name="sender"></param>
 38
 39        /// <param name="e"></param>

 40
 41        private void btn_Start_Click(object sender, EventArgs e)
 42
 43        {
 44
 45            if (!backgroundWorker1.IsBusy)//如果DoWork处于不忙状态,才执行该方法
 46
 47            {
 48
 49                //开始执行异步工作
 50
 51                backgroundWorker1.RunWorkerAsync();
 52
 53            }

 54
 55        }

 56
 57/// <summary>
 58
 59/// 加载的方法
 60
 61/// </summary>
 62
 63/// <param name="sender"></param>
 64
 65/// <param name="e"></param>

 66
 67        private void Form1_Load(object sender, EventArgs e)
 68
 69        {
 70
 71            backgroundWorker1.WorkerReportsProgress = true;//声明异步执行的时候可以报告进度
 72
 73 
 74
 75            backgroundWorker1.WorkerSupportsCancellation = true;//声明可以异步取消
 76
 77           
 78
 79        }

 80
 81        /// <summary>
 82
 83        /// backgroundWorker的核心事件1,执行耗时的操作就在个方法里执行
 84
 85        /// </summary>
 86
 87        /// <param name="sender"></param>
 88
 89        /// <param name="e"></param>

 90
 91        private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
 92
 93        {
 94
 95 
 96
 97           
 98
 99                //模拟100次的执行耗时动作
100
101                for (int i = 0; i < 100; i++)
102
103                {
104
105                    if (backgroundWorker1.CancellationPending)
106
107                    {
108
109                        //直接告诉程序已经执行完了,在实际的项目中,我们可以在界面显示“强行终止”
110
111                        backgroundWorker1.ReportProgress(0"强行终止");
112
113                        break;
114
115                    }

116
117                    GetData();
118
119                    //向主线程报告进度(我们将i当作进度传递给主线程,当循环1次,我们就当做完成1%的工作,并报告给主线程)
120
121                    backgroundWorker1.ReportProgress(i, "");
122
123                
124
125                }

126
127 
128
129        }

130
131        /// <summary>
132
133        /// backgroundWorker的核心事件2,用于接收DoWork方法执行过程中的情况
134
135        /// </summary>
136
137        /// <param name="sender"></param>
138
139        /// <param name="e"></param>

140
141        private void backgroundWorker1_ProgressChanged(object sender, ProgressChangedEventArgs e)
142
143        {
144
145            //接收DoWork传送过来的数据,并在界面上显示
146
147            if(e.UserState.ToString() == "")
148
149            {
150
151                this.lbl_State.Text = e.ProgressPercentage.ToString() + "%";
152
153            }

154
155            else{
156
157                this.lbl_State.Text = e.UserState.ToString() ;
158
159            }

160
161          
162
163        }

164
165        /// <summary>
166
167        /// backgroundWorker的核心事件3,当DoWork方法执行完毕时调用
168
169        /// </summary>
170
171        /// <param name="sender"></param>
172
173        /// <param name="e"></param>

174
175        private void backgroundWorker1_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
176
177        {
178
179            //DoWork执行完时自动调用该方法进行报告
180
181           
182
183      
184
185        }

186
187/// <summary>
188
189/// 取消异步执行的方法
190
191/// </summary>
192
193/// <param name="sender"></param>
194
195/// <param name="e"></param>

196
197        private void btn_Stop_Click(object sender, EventArgs e)
198
199        {
200
201            if (backgroundWorker1.IsBusy)//如果DoWork处于忙状态,才执行该方法
202
203            {
204
205                //开始执行异步工作
206
207                backgroundWorker1.CancelAsync();
208
209            }

210
211        }

212
213    }

214

 

三、BackGroundWorker使用总结

方法:

 backgroundWorker1.CancelAsync() 用于取消异步执行

backgroundWorker1.ReportProgress(int ,object)用于向主线层报告进度

backgroundWorker1.RunWorkerAsync():用于开始执行异步操作

属性:

backgroundWorker1.IsBusy 后台是否会执行

backgroundWorker1.WorkerReportsProgress 声明异步执行时是否可以报告进度

backgroundWorker1.WorkerSupportsCancellation 声明是否可以异步取消

backgroundWorker1.CancellationPending 是否取消异步执行

事件:

DoWork 后台工作的事件

ProgressChanged 接收报告进度的事件

RunWorkerCompleted 异步执行完成的事件

 

 

     其实这个控件很简单,可能看一眼就会使用了,当在实际的开发中,一定可以让你的程序更加友好,效率更高。

 

 

 


原创粉丝点击