• Timer控件Forms.Timer\System.Timers.Timer\System.Threading.Timer


    Timer控件主要有三种分别是:

    1、Forms.Timer

    2、System.Timers.Timer

    3、System.Threading.Timer


    1、Forms.Timer

    常用属性:Interval,Enabled

    事件:Tick

    知识点1:

    启动timer的方法:

    可以使用timer1.Enabled=true;

    也可以使用timer1.Start();

    知识点2:

    Forms.Timer的精度很差,当单次执行时间超过间隔时间,会影响下次触发,精度很差。

      

    知识点3:

    Forms.Timer使用UI主线程,可以修改UI元素;

            private void FormPictureBox_Load(object sender, EventArgs e)
            {
                Console.WriteLine("ui线程"+Thread.CurrentThread.ManagedThreadId);
                timer1.Interval = 2000;
                timer1.Enabled = true;
                timer1.Start();
            }
            private void timer1_Tick(object sender, EventArgs e)
            {
                Console.WriteLine("timer1:"+Thread.CurrentThread.ManagedThreadId);
            }

    结果:


    2、System.Timers.Timer

    System.Timers.Timer  基于服务,轻量

    知识点1:

    属性:Interval,控制时间间隔

    属性:AutoReset,控制单次执行还是重复执行

    属性:Enabled,控制定时器启动,或者使用Start()方法启动定时器,Stop()方法关闭定时器

    事件:Elapsed,执行操作

    知识点2:

    System.Timers.Timer  的Elapsed事件中执行的操作不是由UI线程执行的,

    所以不可以直接修改UI元素,可以通过UI元素的Invoke(new Action())完成,在委托里修改UI元素。

    举例:实现显示事件,效果如下:

     代码:

            private void FormTimer1_Load(object sender, EventArgs e)
            {
                System.Timers.Timer timer = new System.Timers.Timer();
                timer.Interval = 1000;
                timer.AutoReset = true;
                timer.Elapsed += Timer_Elapsed;
                //timer.Start();//使用Start方法启动
                timer.Enabled=true;//使用Enabled属性启动
    
                Console.WriteLine("UI线程:"+Thread.CurrentThread.ManagedThreadId);
            }
    
            private void Timer_Elapsed(object sender, ElapsedEventArgs e)
            {
                Console.WriteLine("timer线程:"+ Thread.CurrentThread.ManagedThreadId);
                this.Invoke(new Action(() =>
                {
                    label2.Text = System.DateTime.Now.ToString();
                    Console.WriteLine("委托线程:" + Thread.CurrentThread.ManagedThreadId);
                }));
            }

    输出:

     从输出结果可以看出:

    Timer_Elapsed事件中执行的内容是在新建线程中执行的,而修改label2.Text的委托实在主线程中执行的。

    
    

    知识点3:

    不用于Forms.Timer,对于耗时操作(耗时事件超过Timer设置的时间间隔),不会影响下一次触发,不会使UI失去响应。

    例如,在Timer_Elapsed事件中执行线程休眠3秒操作,不会影响下一次触发

            private void Timer_Elapsed(object sender, ElapsedEventArgs e)
            {
                Console.WriteLine("timer线程:"+ Thread.CurrentThread.ManagedThreadId);
                this.Invoke(new Action(() =>
                {
                    label2.Text = System.DateTime.Now.ToString();
                    Console.WriteLine("委托线程:" + Thread.CurrentThread.ManagedThreadId);
                }));
    
                Thread.Sleep(3000);
            }

    输出:

    从输出结果中可以看到,对于没有执行完的Timer_Elapsed事件内容,会新建一个线程执行Timer_Elapsed事件

    知识点4:

    线程的终止:

    实例,执行如下效果:

     

    代码:

        System.Timers.Timer timer1;
            private void FormTimer1_Load(object sender, EventArgs e)
            {            
                timer1 = new System.Timers.Timer();
                timer1.Interval = 100;
                timer1.AutoReset = true;
                timer1.Elapsed += Timer1_Elapsed;
                //timer.Start();//使用Start方法启动
                timer1.Enabled = true;//使用Enabled属性启动
            }
    
            int num = 0;
            int result = 0;
            private void Timer1_Elapsed(object sender, ElapsedEventArgs e)
            {
                this.Invoke(new Action(() => lblNumber.Text = num.ToString()));
                if (num <= 100)
                {
                    result += num;
                    num++;
                    this.Invoke(new Action(() => lblResul.Text = result.ToString()));
                }
                else
                {
                    timer1.Stop();
                }
            }

    问题:当任务没有执行完就关闭程序时,会报错,如下:

    报错内容显示,UI线程已经关闭,但是Timer1_Elapsed事件中要执行修改UI元素的任务导致的报错!

     解决方法:在窗体关闭时关闭timer,并在窗体关闭后结束进程。

        private void FormTimer1_FormClosing(object sender, FormClosingEventArgs e)
            {
                if (timer1.Enabled == true)
                    timer1.Stop();
            }
    
            private void FormTimer1_FormClosed(object sender, FormClosedEventArgs e)
            {
                System.Environment.Exit(0);//结束进程
            }

    3、System.Threading.Timer

     System.Threading.Timer与System.Timers.Timer功能相似,都是基于服务,轻量,精度高。

    System.Threading.Timer提供以指定的时间间隔对线程池执行方法的机制

    执行单次运行过长的任务不会影响下次的触发,采用回调方法执行操作。

    不可以直接修改UI元素,需要使用UI元素的Invoke()来实现

    知识点1:

     代码:

    System.Threading.Timer timer1;
    
            private void FormTimer2_Load(object sender, EventArgs e)
            {
                timer1 = new System.Threading.Timer(new System.Threading.TimerCallback(o =>
                {
                    this.Invoke(new Action(() =>
                    {
                        label2.Text = System.DateTime.Now.ToString();
                    }));
                }), null, 100, 1000);
    
            }

     在new System.Threading.Timer的构造函数中,第一个参数是回调函数,第二个参数是一个object,第三个参数是延时,第四个参数是定时周期

     查看回调函数的定义,如下:

    回调函数需要传入一个Object类型参数,其实这个Object类型参数就是Timer构造函数中的第二个参数,举例:

     输入结果如下:

     

    知识点2:

    在FlowlayoutPanel中连续添加多个lable

     代码:

    int count = 20;
            int i = 1;
            private void button1_Click(object sender, EventArgs e)
            {
                timer2 = new System.Threading.Timer(new System.Threading.TimerCallback(o =>
                {
                    Action act = addLable;
                    this.Invoke(act);
                }), null, 100, 1000);
            }
    
            public void addLable()
            {
                if (i <= count)
                {
                    Label lbl = new Label();
                    lbl.Name = "lbl" + i;
                    lbl.Text = "座位" + i;
                    lbl.Size = new System.Drawing.Size(60, 30);
                    lbl.TextAlign = System.Drawing.ContentAlignment.MiddleCenter;
                    lbl.Click += Lbl_Click;
                    flowLayoutPanel1.Controls.Add(lbl);
                    i++;
                }
                else
                {
                    timer2.Dispose();
                }
    
            }
    
            private void Lbl_Click(object sender, EventArgs e)
            {
                Label lbl = sender as Label;
                if (lbl.BackColor != Color.Red)
                {
                    lbl.BackColor = Color.Red;
                }
                else
                {
                    lbl.BackColor = Color.Gray;
                }
            }

    知识点3:

    停止timer工作

    private void FormTimer2_FormClosing(object sender, FormClosingEventArgs e)
            {
                timer1.Dispose();
                timer2.Dispose();
            }
            private void FormTimer2_FormClosed(object sender, FormClosedEventArgs e)
            {
                System.Environment.Exit(0);
            }
  • 相关阅读:
    iOS的生命周期
    【iOS开发】在 App 中加入 AdMob 广告
    iOS性能优化:Instruments
    动态的计算行高 加载数据源 有多少显示多少 tableView 包含 colloctionView 显示复杂的界面写法
    Java String.split()注意点
    Java eclipse export jar包 包括第三方引入的jar
    微信网页授权获取用户基本信息
    android连接本地tomcat服务器,报timeout
    iOS内存管理retain,assign,copy,strong,weak
    static与全局与局部变量的区别
  • 原文地址:https://www.cnblogs.com/hanzq/p/16797567.html
Copyright © 2020-2023  润新知