zoukankan      html  css  js  c++  java
  • C# Timer 定时器

    Timer简单介绍

    构造函数

    通过ILSpy反编译可以看到Timer的内部代码。

    Timer 的默认构造函数里赋了初值,所以当我们初始化Timer的时候,已经有了默认值。

    Timer 的带参数的构造函数会重新给 interval(获取或设置引发 Elapsed 事件的间隔,以毫秒为单位。)赋值。

    Elapsed事件(达到间隔时发生

    匿名函数传递

    System.Timers.Timer t = new System.Timers.Timer(1000 * 60 * 10); //实例化,设置时间间隔为十分钟,此处参数单位为毫秒。//匿名函数传递
    t.Elapsed += (s, e) =>
    {
        print(DateTime.Now);
    };

    非匿名函数传递

    System.Timers.Timer t = new System.Timers.Timer(1000 * 60 * 10); //实例化,设置时间间隔为十分钟,此处参数单位为毫秒。
    t.Elapsed += new System.Timers.ElapsedEventHandler((s, e) => print(DateTime.Now));//非匿名函数传递

    下面是写在 Global.asax.cs 里例子,项目启动的时候会执行:

    //第一个访问网站的用户会触发该方法。
    protected void Application_Start()
    {
        DateTime dt = DateTime.Now;
    System.Timers.Timer t = new System.Timers.Timer(1000 * 60 * 10); //实例化,设置时间间隔为十分钟,此处参数单位为毫秒 t.Elapsed += new System.Timers.ElapsedEventHandler((s, e) => print(dt)); t.AutoReset = true; //每到指定时间Elapsed事件是触发一次(false),一直触发(true) t.Enabled = true; //是否触发Elapsed事件 t.Start(); }

    定时器

    现在我们有个需求,需要每天12点来触发 print 方法,那么我们需要利用 Timer 写一个定时器。通过更改 Interval 属性的数值,来调整触发方法的时间。

    下面是demo

    private static readonly System.Timers.Timer Timer = new System.Timers.Timer(); //初始化。
    private static DateTime dt = new DateTime(); //固定时间。
    
    /// <summary>
    /// 程序入口(自行调用)
    /// </summary>
    /// <param name="timing">定时时间(格式:年月日时分秒)</param>
    public void Init()
    {
        dt = DateTime.Now;
        SetInterval();
        Timer.Elapsed += new System.Timers.ElapsedEventHandler((s, e) => SetInterval());
    }
    
    /// <summary>
    /// 定时器
    /// </summary>
    /// <param name="timing">定时时间(格式:年月日时分秒)</param>
    private void SetInterval()
    {
        Timer.Stop();
        var now = DateTime.Now;
        if (now >= dt)//如果当前时间>=定时时间
        {
            //定时结束之后,你要执行的代码
            print(now);
            //----------------------------------------------------------
            //此处可修改dt。更改需求。
            //----------------------------------------------------------
            dt = DateTime.Now.Date.AddDays(1).AddHours(12); //重新计算定时时间,第二天12点再执行。
            //dt = DateTime.Now.AddMinutes(0.1);//重新计算定时时间,每分钟执行一次。
            SetInterval();
        }
        else//如果当前时间<定时时间
        {
            Timer.Interval = dt.Subtract(now).TotalMilliseconds;//重新计算定时时间,按毫秒计算。
            Timer.Start();
        }
    }
    
    /// <summary>
    /// 测试输出
    /// </summary>
    public void print(DateTime dt)
    {
        num++;
        Console.WriteLine("执行第{0}次,时间:{1}", num, dt);
    }
    固定时间定时器

    效果:

    现在需求变更为每天11点到下午17点的时候触发,间隔1分钟。

    下面是demo

    private static readonly System.Timers.Timer Timer = new System.Timers.Timer(); //初始化。
    private static DateTime dtStar = new DateTime(); //时间段--开始时间。
    private static DateTime dtEnd = new DateTime(); //时间段--结束时间。
    private static int intervalTime = 10;//间隔时间(分钟)。
    
    /// <summary>
    /// 程序入口(自行调用)
    /// </summary>
    /// <param name="timing">定时时间(格式:年月日时分秒)</param>
    public void Init()
    {
        dtStar = DateTime.Now.Date.AddDays(0).AddHours(11);//今天11点。
        dtEnd = DateTime.Now.Date.AddDays(0).AddHours(17);//今天17点。
        intervalTime = 1;//每1分钟执行一次。
        SetInterval();
        Timer.Elapsed += new System.Timers.ElapsedEventHandler((s, e) => SetInterval());
    }
    
    /// <summary>
    /// 定时器(间断)
    /// </summary>
    /// <param name="timing">起始时间</param>
    private void SetInterval()
    {
        Timer.Stop();
        var now = DateTime.Now;
        if (now.Hour >= dtStar.Hour && now.Date == dtStar.Date)//达到开始时间,并且是今天
        {
            if (dtEnd.Subtract(now).TotalMinutes >= intervalTime)//小于结束时间
            {
                print(now);//打印
                //----------------------------------------------------------
                //此处可修改dtStar,dtEnd,intervalTime,三个参数。更改需求。
                //----------------------------------------------------------
                Timer.Interval = now.AddMinutes(intervalTime).Subtract(now).TotalMilliseconds;
                Timer.Start();
            }
            else
            {
                //----------------------------------------------------------
                //此处可修改dtStar,dtEnd,intervalTime,三个参数。更改需求。
                //----------------------------------------------------------
                dtStar = DateTime.Now.Date.AddDays(1).AddHours(11);//第二天11点。
                dtEnd = DateTime.Now.Date.AddDays(1).AddHours(17);//第二天17点。
                intervalTime = 2;//每2分钟执行一次。
                Timer.Interval = dtStar.Subtract(now).TotalMilliseconds;
                Timer.Start();
            }
        }
        else//如果 定时时间>当前时间
        {
            Timer.Interval = dtStar.Subtract(now).TotalMilliseconds;//重新计算定时时间,按毫秒计算。
            Timer.Start();
        }
    }
    
    /// <summary>
    /// 测试输出
    /// </summary>
    public void print(DateTime dt)
    {
        num++;
        Console.WriteLine("执行第{0}次,时间:{1}", num, dt);
    }
    间断时间定时器
  • 相关阅读:
    app启动优化
    CountDownLatch妙用
    匿名内部类为什么有可能造成内存泄漏
    单例模式为什么有可能造成内存泄漏
    左移右移记不住怎么办
    说一说ThreadLocal
    对framework层的一些看法
    双重锁单例
    JMM总结
    关于lock前缀
  • 原文地址:https://www.cnblogs.com/cang12138/p/5845743.html
Copyright © 2011-2022 走看看