线程系列10,无需显式调用线程的情形

通常,我们会通过线程的构造函数先创建线程再使用线程。而实际上,.NET中有些类提供的方法,其内部就是使用多线程处理的。一些封装了多线程、异步处理方法的类都符合了"事件驱动异步模式(event-based asynchronous pattern)"。以System.ComponentModel下的BackgroundWorker类来说,该类就符合这种模式。

 

BackgroundWorker类属性:
WorkerSupportsCancellation:设置为true表示允许取消
WorkerReportProgress:设置为true表示可显示进度

 

BackgroundWorker类事件:
DoWork:后台线程要做的事
ProgressChanged:进度触发事件
RunWorkerCompleted:当进度结束、抛出异常、或取消执行时触发

 

举例,在Windows窗体应用程序中使用BackgroundWorker类。

→新建一个Windows窗体应用程序,界面包括2个button,1个label,1个progressbar,1个BackgournWorker控件。

→设置BackgournWorker控件的WorkerSupportsCancellation属性和WorkerReportProgress为true。

→后台代码为:

       private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)

        {

            int sum = 0;

            for (int i = 1; i <=100; i++)

            {

                Thread.Sleep(1000);

                sum = sum + 1;

                backgroundWorker1.ReportProgress(i);

                //如果取消计算

                if (backgroundWorker1.CancellationPending)

                {

                    e.Cancel = true;

                    backgroundWorker1.ReportProgress(0);

                    return;

                }

                e.Result = sum;

            }

        }

        private void backgroundWorker1_ProgressChanged(object sender, ProgressChangedEventArgs e)

        {

            //把BackgroundWorker的进程体现到ProgressBar上

            progressBar1.Value = e.ProgressPercentage;

            //把BackgroundWorker的进程体现到label上

            label1.Text = e.ProgressPercentage + "%";

        }

        private void backgroundWorker1_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)

        {

            if (e.Cancelled) //可能以取消的方式结束

            {

                label1.Text = "计算被取消";

            }

            else if (e.Error != null)//可能以抛出异常的方式结束

            {

                label1.Text = e.Error.Message;

            }

            else//可能正常结束

            {

                label1.Text = "1到100的和为:" + e.Result.ToString();

            }

        }

        //开始计算

        private void btnCalculate_Click(object sender, EventArgs e)

        {

            if (!backgroundWorker1.IsBusy)

            {

                backgroundWorker1.RunWorkerAsync();

            }

        }

        //取消计算

        private void btnCancel_Click(object sender, EventArgs e)

        {

            if (backgroundWorker1.IsBusy)

            {

                backgroundWorker1.CancelAsync();

            }

            

        }

 

在DoWork事件中:
○ BackgroundWorker的实例方法ReportProgress,用来把后台线程进展情况显示到进度条。
○ 把DoWork的计算结果保存到DoWorkEventArgs类型的Result属性中

 

在ProgressChanged事件中:
○ 把该事件的ProgressChangedEventArgs类型参数的ProgressPercentage属性值分别显示到进度条和label

 

在RunWorkerCompleted事件中:
○ 该事件的RunWorkerCompletedEventArgs类型参数的Cancelled属性值用来判断是否取消
○ RunWorkerCompletedEventArgs类型参数的Error属性值用来记录异常
○ RunWorkerCompletedEventArgs类型参数的Result属性值取出在DoWork事件中,为DoWorkEventArgs类型的Result属性设置的值

 

47
点击"开始计算"按钮,后台线程运行并显示到进度条和label上。

 

线程系列包括:

线程系列01,前台线程,后台线程,线程同步

线程系列02,多个线程同时处理一个耗时较长的任务以节省时间

线程系列03,多线程共享数据,多线程不共享数据

线程系列04,传递数据给线程,线程命名,线程异常处理,线程池

线程系列05,手动结束线程

线程系列06,通过CLR代码查看线程池及其线程

线程系列07,使用lock语句块或Interlocked类型方法保证自增变量的数据同步

线程系列08,实现线程锁的各种方式,使用lock,Montor,Mutex,Semaphore以及线程死锁

线程系列09,线程的等待、通知,以及手动控制线程数量

线程系列10,无需显式调用线程的情形

你可能感兴趣的:(线程)