System.Timers.Timer定时器的一些问题 做个笔记

      最近在写一个控制台程序,需要用到定时器,因为没怎么写过控制台程序,所以后来确定了使用System.Timers.timer定时器,在使用的过程中,也就遇到了些问题,比如:   我在主程序中设定了一个定时器,设置了该定时器的一些参数(如:间隔时间,启动定时器,定时器的 Elapsed事件),然后在使用的时候,会发现当 Elapsed事件的执行时间超过了该定时器的间隔的话,会产生一些不好的后果,又或者当我们在该定时器的 Elapsed事件里面在设定一个定时器,当Elapsed事件的执行时间超过主定时器的间隔,也会产生不好的效果,这样的话我们怎么来解决呢?然我们用代码来看看。

    首先我们来看下当 Elapsed事件的执行时间大于定时器的间隔的话,会发生怎样的事情。

 

 
using System;
using System.Collections.Generic;
using System.Text;
using System.Timers;
namespace ConsoleTesk
{
    class Program
    {
        static Timer timerOne = new Timer();
        static int num = 0;
        static int i = 0;
        static void Main(string[] args)
        {

            timerOne.Interval = 1000 * 1;//设定定时器执行间隔为1s                            
            timerOne.Elapsed += new ElapsedEventHandler(timerOne_Elapsed);
            timerOne.Enabled = true;
            string readLine;
            do
            {
                readLine = Console.ReadLine();
            } while (readLine != null && readLine != "exit");
        }
        private static void timerOne_Elapsed(object source, ElapsedEventArgs e)
        {
            i++;
            if (i <= 5)
            {
                Method();
            }
        }
        private static void Method()
        {
            Console.WriteLine(DateTime.Now.ToString());
            Timer timerSecond = new Timer();
            timerSecond.Interval = 1000 * 2;//设定定时器执行间隔为2s
            timerSecond.Elapsed += new ElapsedEventHandler(timerSecond_Elapsed);
            timerSecond.Enabled = true;

        }
        private static void timerSecond_Elapsed(object source, ElapsedEventArgs e)
        {

            Timer s = (Timer)source;
            Console.WriteLine("123456");
            s.Enabled = false;
            s.Dispose();
        }
    }
}

编译后运行得到的结果是:

我们能看到当Elapsed事件的执行时间大于定时器的间隔的话,很显然得到的结果不是我们想要的,我找到的解释是:

Elapsed 事件在 ThreadPool 线程上引发。如果 Elapsed 事件的处理时间比 Interval 长,在另一个 ThreadPool 线程中将会再次引发此事件。因此,事件处理程序应当是可重入的。那么我们怎样才能达到我们想要的效果呢?修正后程序为:

using System;
using System.Collections.Generic;
using System.Text;
using System.Timers;
namespace ConsoleTesk
{
    class Program
    {
        static Timer timerOne = new Timer();
        static object lockNum = new object();
        static object lockNum2 = new object();
        static int num = 0;
        static int i = 0;
        static void Main(string[] args)
        {

            timerOne.Interval = 1000 * 1;  //设定定时器的间隔为1s
            timerOne.Elapsed += new ElapsedEventHandler(timerOne_Elapsed);
            timerOne.Enabled = true;
            string readLine;
            do
            {
                readLine = Console.ReadLine();
            } while (readLine != null && readLine != "exit");
        }
        private static void timerOne_Elapsed(object source, ElapsedEventArgs e)
        {
            i++;
            if (i <= 5)
            {
                Method();
            }
        }
        private static void Method()
        {
            timerOne.Enabled = false;//设置第一个定时器为停止
            Console.WriteLine(DateTime.Now.ToString());
            Timer timerSecond = new Timer();
            timerSecond.Interval = 1000 * 4;//设定定时器的间隔为4s
            timerSecond.Elapsed += new ElapsedEventHandler(timerSecond_Elapsed);
            timerSecond.Enabled = true;

        }
        private static void timerSecond_Elapsed(object source, ElapsedEventArgs e)
        {
            num++;
            Timer s = (Timer)source;
            Console.WriteLine("123456");
            if (num > 2)
            {
                s.Enabled = false;
                s.Dispose();
                timerOne.Enabled = true;//当第二个定时器执行完毕后启动后启动第一个定时器
                num = 0;
            }
        }
    }
}

得到的结果是:

结果完全符合我们的要求。

posted on 2012-04-17 21:48  小菜接口  阅读(3923)  评论(5编辑  收藏  举报

导航