【问题标题】:How to set timer to execute at specific time in c#如何在c#中设置定时器在特定时间执行
【发布时间】:2014-02-13 11:19:59
【问题描述】:

我有一个要求,我需要在每天上午 00:01:00 执行计时器......但我不知道如何实现这一点..如果我正在占用系统时间,它可以采用不同的格式。 . 这是我的计时器代码..

static System.Timers.Timer timer;
timer = new System.Timers.Timer();
timer.Interval = 1000 * 60 * 60 * 24;//set interval of one day
timer.Elapsed += new ElapsedEventHandler(timer_Elapsed);
start_timer(); 

static void timer_Elapsed(object sender, ElapsedEventArgs e)
    {
        // Add timer code here

    }
    private static void start_timer()
    {
        timer.Start();
    }

【问题讨论】:

  • Nico 的回答将不准确或不可靠。格兰特的答案是更好的解决方案,您需要对 DateTime.Now 进行轮询和检查

标签: c# multithreading timer


【解决方案1】:

如果您想在凌晨 00:01:00 开始计时,请执行一些处理时间,然后重新启动计时器,您只需要计算 Now 和下一个上午 00:01:00 时隙之间的差异,例如。

static Timer timer;
static void Main(string[] args)
{
    setup_Timer();
}

static void setup_Timer()
{
    DateTime nowTime = DateTime.Now;
    DateTime oneAmTime = new DateTime(nowTime.Year, nowTime.Month, nowTime.Day, 0, 1, 0, 0);
    if (nowTime > oneAmTime)
        oneAmTime = oneAmTime.AddDays(1);

    double tickTime = (oneAmTime - nowTime).TotalMilliseconds;
    timer = new Timer(tickTime);
    timer.Elapsed += timer_Elapsed;
    timer.Start();
}

static void timer_Elapsed(object sender, ElapsedEventArgs e)
{
    timer.Stop();
    //process code..
    setup_Timer();
}

【讨论】:

【解决方案2】:

你应该做的是编写你的程序来完成你需要它做的任何事情,然后使用你的操作系统的内置任务调度程序来启动它。那应该是最靠谱的。例如,Windows 的任务计划程序可以在用户登录之前启动您的应用,在必要时处理重新启动应用,记录错误并发送通知等。

否则,您必须 24/7 全天候运行您的应用,并让它定期轮询时间。

例如,您可以每分钟更改一次间隔:

timer.Interval = 1000 * 60;

在您的 Elapsed 事件中,检查当前时间:

static void timer_Elapsed(object sender, ElapsedEventArgs e)
{
    if (DateTime.Now.Hour == 1 && DateTime.Now.Minute == 0)
    {
        // do whatever
    }
}

但这确实不可靠。您的应用可能会崩溃。处理 DateTime 可能会很棘手。

【讨论】:

    【解决方案3】:

    你总是可以计算出来的:

    static void timer_Elapsed(object sender, ElapsedEventArgs e)
    {
        // Do stuff
    
        start_timer();
    }
    
    private static void start_timer()
    {
        timer.Interval = CalculateInterval();
        timer.Start();
    }
    
    private static double CalculateInterval()
    {
        // 1 AM the next day
        return (DateTime.Now.AddDays(1).Date.AddHours(1) - DateTime.Now).TotalMilliseconds;
    }
    
    【解决方案4】:

    这是一个计时器实现,它采用一个间隔(就像任何其他计时器一样)并在该间隔到期时准确触发,即使机器在其间进入睡眠模式。

    public delegate void TimerCallbackDelegate(object sender, ElapsedEventArgs e);
    public class TimerAbsolute : System.Timers.Timer
    {
        private DateTime m_dueTime;
        private TimerCallbackDelegate callback;
    
        public TimerAbsolute(TimerCallbackDelegate cb) : base()
        {
            if (cb == null)
            {
                throw new Exception("Call back is NULL");
            }
            callback = cb;
            this.Elapsed += this.ElapsedAction;
            this.AutoReset = true;
        }
    
        protected new void Dispose()
        {
            this.Elapsed -= this.ElapsedAction;
            base.Dispose();
        }
    
        public double TimeLeft
        {
            get
            {
                return (this.m_dueTime - DateTime.Now).TotalMilliseconds;
            }
        }
    
        public int TimeLeftSeconds
        {
            get
            {
                return (int)(this.m_dueTime - DateTime.Now).TotalSeconds;
            }
        }
    
    
        public void Start(double interval)
        {
            if (interval < 10)
            {
                throw new Exception($"Interval ({interval}) is too small");
            }
    
            DateTime dueTime = DateTime.Now.AddMilliseconds(interval);
    
            if (dueTime <= DateTime.Now)
            {
                throw new Exception($"Due time ({dueTime}) should be in future. Interval ({interval})");
            }
            this.m_dueTime = dueTime;
    
            // Timer tick is 1 second
            this.Interval = 1 * 1000;
            base.Start();
        }
    
        private void ElapsedAction(object sender, System.Timers.ElapsedEventArgs e)
        {
            if (DateTime.Now >= m_dueTime)
            {
                // This means Timer expired
                callback(sender, e);
                base.Stop();
            }
        }
    }
    

    【讨论】:

      猜你喜欢
      • 2010-09-05
      • 1970-01-01
      • 1970-01-01
      • 2012-02-21
      • 2021-09-18
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-03-03
      相关资源
      最近更新 更多