System.Timers.Timer定时器的多线程方式

定时器相信大家都使用过,但是定时器在使用时有时候也会碰到问题。定时在工作时,其实也相当于开多线程的方式执行,即程序在执行过程中,定时器是严格按照你定义的时间间隔来执行的。在当前的任务中没有执行完成时,定时器会重新开一个线程再执行任务,定时器不会负责检测前面一个任务是否执行完毕,他是应该会检查当前的线程是否执行完结,以备下一次任务执行。

现在贴出测试程序代码

/// <summary>
    /// 测试定时器
    /// </summary>
    internal class TimerSimple
    {
        public static void Start()
        {
            System.Timers.Timer timer = new System.Timers.Timer();
            timer.Enabled = true;
            timer.Interval = 5000; //每5秒执行一次
            timer.Elapsed += new System.Timers.ElapsedEventHandler(timer_Elapsed);
            timer.Start();
        }

        static void timer_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
        {
            Console.WriteLine("Current start time:" + DateTime.Now.ToString() + " ThreadID:" + Thread.CurrentThread.ManagedThreadId.ToString());
            //当前任务需要执行15秒
            Thread.Sleep(15000);
            Console.WriteLine("Current time:" + DateTime.Now.ToString() + " ThreadID:" + Thread.CurrentThread.ManagedThreadId.ToString());
        }
    }

运行结果:

定时器是每5秒执行一次,而任务则是需要执行15秒,于是发现该服务会开启多个线程执行该任务。相信对时间也没问题,但是具体的该服务能开多少个线程呢?我明天再测试一把。

所以,大家在用定时器的时候,可以注意,改掉以上代码就成了介个样子

 /// <summary>
    /// 测试定时器
    /// </summary>
    internal class TimerSimple
    {
        //将定时器移到该位置
        static System.Timers.Timer timer = new System.Timers.Timer();
        public static void Start()
        {
            
            timer.Enabled = true;
            timer.Interval = 5000; //每5秒执行一次
            timer.Elapsed += new System.Timers.ElapsedEventHandler(timer_Elapsed);
            timer.Start();
        }

        static void timer_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
        {            
            Console.WriteLine("Current start time:" + DateTime.Now.ToString() + " ThreadID:" + Thread.CurrentThread.ManagedThreadId.ToString());
            timer.Elapsed -= new System.Timers.ElapsedEventHandler(timer_Elapsed);  //取消定时器
            //当前任务需要执行15秒,使用循环
            while (true)
            {
                Thread.Sleep(15000);
                Console.WriteLine("Current time:" + DateTime.Now.ToString() + " ThreadID:" + Thread.CurrentThread.ManagedThreadId.ToString());
            }
        }
    }


运行结果就成了介个样子

至少该方式能开多少个线程,等闲的时候再进行测试吧。

该场景应用在实际的场景中:

使用多个服务,分等级从数据库中定时取数据,POST到特定的网页,如果数据量一次性6000以上时,就会出现数据库死锁,如果有日志,则还会发现,有可能出现服务崩溃的情况。以前自己没搞清楚,这是多么深的领悟啊。

 

 

posted @ 2013-10-27 23:22  124882511  阅读(2016)  评论(0)    收藏  举报