How to use the .NET Timer class to trigger an event at a specific time?

前端 未结 9 1678

I would like to have an event triggered in my app which runs continuously during the day at a certain time, say at 4:00pm. I thought about running the timer every second and

相关标签:
9条回答
  • 2020-12-01 00:28

    I did this way to fire 7am every morning

    bool _ran = false; //initial setting at start up
        private void timer_Tick(object sender, EventArgs e)
        {
    
            if (DateTime.Now.Hour == 7 && _ran==false)
            {
                _ran = true;
                Do_Something();               
    
            }
    
            if(DateTime.Now.Hour != 7 && _ran == true)
            {
                _ran = false;
            }
    
        }
    
    0 讨论(0)
  • 2020-12-01 00:29

    How about something like this, using the System.Threading.Timer class?

    var t = new Timer(TimerCallback);
    
    // Figure how much time until 4:00
    DateTime now = DateTime.Now;
    DateTime fourOClock = DateTime.Today.AddHours(16.0);
    
    // If it's already past 4:00, wait until 4:00 tomorrow    
    if (now > fourOClock)
    {
        fourOClock = fourOClock.AddDays(1.0);
    }
    
    int msUntilFour = (int)((fourOClock - now).TotalMilliseconds);
    
    // Set the timer to elapse only once, at 4:00.
    t.Change(msUntilFour, Timeout.Infinite);
    

    Note that if you use a System.Threading.Timer, the callback specified by TimerCallback will be executed on a thread pool (non-UI) thread—so if you're planning on doing something with your UI at 4:00, you'll have to marshal the code appropriately (e.g., using Control.Invoke in a Windows Forms app, or Dispatcher.Invoke in a WPF app).

    0 讨论(0)
  • 2020-12-01 00:31

    .NET has lots of timer classes, but they all take time spans relative to the current time. With a relative time, there are lots of things to consider before you start your timer and to monitor for while your timer is running.

    • What if the computer goes into a standby state?
    • What if the computer's time changes?
    • What if the expiration time is after a daylight savings time transition?
    • What if the user changes the computer's time zone after you started your timer such that there is a new time zone transition before expiration that wasn't previously there?

    The operating system is in a great place to handle this complexity. Application code running on .NET is not.

    For Windows, the NuGet package AbsoluteTimer wraps an operating system timer that expires at an absolute time.

    0 讨论(0)
  • 2020-12-01 00:31

    How about this solution?

    Sub Main()
      Dim t As New Thread(AddressOf myTask)
      t.Start()
      Console.ReadLine()
    End Sub
    
    Private Sub myTask()
      Dim a = "14:35"
      Dim format = "dd/MM/yyyy HH:mm:ss"
      Dim targetTime = DateTime.Parse(a)
      Dim currentTime = DateTime.Parse(Now.ToString(format))
      Console.WriteLine(currentTime)
      Console.WriteLine("target time " & targetTime)
      Dim bb As TimeSpan = targetTime - currentTime
      If bb.TotalMilliseconds < 0 Then
        targetTime = targetTime.AddDays(1)
        bb = targetTime - currentTime
      End If
      Console.WriteLine("Going to sleep at " & Now.ToString & " for " & bb.TotalMilliseconds)
      Thread.Sleep(bb.TotalMilliseconds)
      Console.WriteLine("Woke up at " & Now.ToString(format))
    End Sub
    
    0 讨论(0)
  • 2020-12-01 00:34

    You can use Task Sceduler on windows See daily trigger example for detail.

    or use bellow code if you want wrote it yourself:

    public void InitTimer()
    {
        DateTime time = DateTime.Now;
        int second = time.Second;
        int minute = time.Minute;
        if (second != 0)
        {
            minute = minute > 0 ? minute-- : 59;
        }
    
        if (minute == 0 && second == 0)
        {
            // DoAction: in this function also set your timer interval to 24 hours
        }
        else
        {
            TimeSpan span = //new daily timespan, previous code was hourly: new TimeSpan(0, 60 - minute, 60 - second);
            timer.Interval = (int) span.TotalMilliseconds - 100; 
            timer.Tick += new EventHandler(timer_Tick);
            timer.Start();
        }
    }
    
    void timer_Tick(object sender, EventArgs e)
    {
        timer.Interval = ...; // 24 hours
        // DoAction
    }
    
    0 讨论(0)
  • 2020-12-01 00:38

    Starting with .NET 4.5 there's a really clean solution:

    public async void ScheduleAction(Action action, DateTime ExecutionTime)
    {
        await Task.Delay((int)ExecutionTime.Subtract(DateTime.Now).TotalMilliseconds);
        action();
    }
    

    Here's a solution without async/await:

    public void Execute(Action action, DateTime ExecutionTime)
    {
        Task WaitTask = Task.Delay((int)ExecutionTime.Subtract(DateTime.Now).TotalMilliseconds);
        WaitTask.ContinueWith(_ => action);
        WaitTask.Start();
    }
    

    It should be noted that this only works for about 24 days out because of int32 max value, which is plenty for your case, but worth noting.

    0 讨论(0)
提交回复
热议问题