线程实用解析--------(五)BackgroundWorker和Timer

上一节讲到在实际的编程中某些任务执行完成时间可能较长,比如打开大文件、连接远程计算机或查询数据库,这个时候可能会导致UI界面发生长时间未响应,如果你需要在执行某些任务的同时,还要进行UI界面的响应,BackgroundWorker是您最好的选择,同时,从VS2005开始也BackgroundWorker组件,这使Backgroundworker使用起来更加的方便。

下面我会通过一个更新UI界面进度条的例子来向大家逐步的讲解BackgroundWorker类

首先新建一个Form应用程序,在UI也添加一个按钮和一个进度条processbar

如图所示:

然后进入.cs页

先声明一个全局的BackgroundWorker 实例

Private BackgroundWorker backgroundWorker = new BackgroundWorker();

        private static int sum = 0;//定义一个全局的sum,下边函数计数用

然后在Buntton_Click(object sender, EventArgs e)

{

    //DoWork 事件在调用RunWorkerAsync()函数时发生,该事件是在另一个线程里执行的,该线程属于线程池中的一个线程。所以,不能在这个事件中操作UI元素

    backgroundworker.DoWork += new DoWorkEventHandler(backgroundworker_DoWork);

   //触发DoWork事件,同时RunWorkerAsync的参数即为DoWork()函数所需的参数,如果参数过多,可以先将参数封装成类,再进行传递

   backgroundworker.RunWorkerAsync(10);

   //获取或设置一个值,该值指示BackgroundWorker能否报告进度更新,在用于更新进度条等的操作中,需要将该值设置为true
  backgroundworker.WorkerReportsProgress = true;

 //在实际使用中往往使用给方法和事件更新进度条或者日志信息,通过ReportProgress()来触发该事件
  backgroundworker.ProgressChanged+=new ProgressChangedEventHandler(backgroundworker_ProgressChanged);

  //后台操作结束、或取消、异常等会触发该事件,相当于委托中AsyncCallback事件,该事件是在创建控件的线程中执行的 

backgroundworker.RunWorkerCompleted+=new RunWorkerCompletedEventHandler(backgroundworker_RunWorkerCompleted);

}

//随时的显示更新进度

  void backgroundworker_ProgressChanged(object sender, ProgressChangedEventArgs e)

        {

            progressBar1.Value = e.ProgressPercentage;//随着后台操作的执行,不断的更新进度

        }

//在后台任务执行完之后,将进程条的设为100

Void backgroundworker_RunWorkerCompleted(objec tsender, RunWorkerCompletedEventArgs e)

        {

            MessageBox.Show("求和结果为:" + sum+"当前的线程为:"+Thread.CurrentThread.ManagedThreadId);

            progressBar1.Value = 100;

        }

//该事件中进行耗时的操作,但是不要涉及对UI元素的操作

        void backgroundworker_DoWork(object sender, DoWorkEventArgs e)

        {

          MessageBox.Show("DoWork所在的线程为:" + Thread.CurrentThread.ManagedThreadId+"是否为后台线程:"+Thread.CurrentThread.IsBackground);

            int a = (int)e.Argument;

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

            {

                sum += i;

                Thread.Sleep(500);

//通过执行该方法,触发ProgressChanged事件,不断的更新processbar的值

                backgroundworker.ReportProgress(sum);            }

        }

实验结果如下:

通过以上这个例子,相信你基本已经可以自主的运用BackgroundWorker类了,最后再将BackgroundWorker类进行一个总结:

BackgroundWorker对象有三个主要的事件:

  DoWork - 当BackgroundWorker对象的多线程操作被执行时触发。

  RunWokerCompleted - 当BackgroundWoker对象的多线程操作完成时触发。

  ProgressChanged - 当BackgroundWorker对象的多线程操作状态改变时触发。

  如果想让BackgroundWorker对象以异步的方式报告线程实时进度,必须将属性WorkerReportsProgress的值设为true。BackgroundWorker对象的ReportProgress方法用于向主线程返回后台线程执行的实时进度。

关于BackgroundWorker就介绍到这里,下面介绍Timer类

Timer类

关于Timer类.NET中有三个Timer,分别是: System.Windows.Forms.Timer,System.Timers.Timer,System.Threading.Timer 。 

System.Windows.Forms.Timer主要用于依赖于WinForm程序中的窗体,Timer代码直接运行于UI线程中,所以可以操作UI控件。

System.Timers.Timer可以用在Component 或者一般的类里,该Timer的事件默认执行线程池中一个线程,如果需要让代码执行在某个特定线程中,需要通过设置TimerSynchronizingObject 属性

System.Threading.Timer,可以在任何多线程环境中使用Timer,该事件也是在线程池中的线程上执行的。

System.Timers.Timer应用示例:

先将Form窗体中放置一个Button,将ButtonText属性设为Timer

Button_Click(object sender, EventArgs e)

        {

System.Windows.Forms.Timer timer = new System.Windows.Forms.Timer();

            timer.Tick += new EventHandler(timer_Tick);

            timer.Interval = 1000;//设置Interval属性,每隔多少秒就触发Tick事件

            timer.Start();

        }

        void timer_Tick(object sender, EventArgs e)

        {

            button8.Text = DateTime.Now.ToLocalTime().ToString();

        }

通过System.Windows.Forms.Timer可以很容易的操作Ui界面的控件,比如本例可以通过ButtonText属性来显示当前的时间。

实验结果如图:

System.Threading.Timer示例:

Button_Click(object sender, EventArgs e)

        {

//System.Threading.Timer的构造函数有5个重载,基本上都差不多。第一个参数为一个TimerCallback的委托,第二个参数为委托调用函数所需的参数,如果没有可以设置为null,第三个为调用callback之前的延迟时间,第四个调用callback的时间间隔。

System.Threading.Timer timer1 = new System.Threading.Timer(new TimerCallback(Count), 10, 5000, 10);

}

Private static void Count(object obj)

{

   Int a=(int)obj;

For(int i=0;i<a;i++)

{

 Sum+=1;

}

MessageBox.Show("Sum的值:"+sum);

}

实验结果:因为每个10毫秒就要触发一个Count事件,所以会一直不停的弹出MessageBoxsum是一个全局变量,所以会不断的累加。

关于System.Timers.Timer就不再过多的介绍了,希望有兴趣的朋友下去自己了解。

这一节就到这里了,希望可以对大家有所帮助,还请大家多多指教。

 

  • 0
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值