Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

System.Timers.Timer How to get the time remaining until Elapse

Tags:

Using C#, how may I get the time remaining (before the elapse event will occur) from a System.Timers.Timer object?

In other words, let say I set the timer interval to 6 hours, but 3 hours later, I want to know how much time is remaining. How would I get the timer object to reveal this time remaining?

like image 568
Lonnie Best Avatar asked Feb 17 '10 05:02

Lonnie Best


People also ask

What does timer elapsed mean?

Elapsed time is the amount of time that passes from the start of an event to its finish. In simplest terms, elapsed time is how much time goes by from one time (say 3:35pm) to another (6:20pm). An important tool that goes hand and hand with elapsed time is the clock.

How do I stop a timer elapsed event?

It would have already queued before you have called Stop method. It will fire at the elapsed time. To avoid this happening set Timer. AutoReset to false and start the timer back in the elapsed handler if you need one.

How does system timer work?

Remarks. The Timer component is a server-based timer that raises an Elapsed event in your application after the number of milliseconds in the Interval property has elapsed. You can configure the Timer object to raise the event just once or repeatedly using the AutoReset property.

Does system timers timer run in a separate thread?

Yes, they run in a different thread.


2 Answers

The built-in timer doesn't provide the time remaining until elapse. You'll need to create your own class which wraps a timer and exposes this info.

Something like this should work.

public class TimerPlus : IDisposable {     private readonly TimerCallback _realCallback;     private readonly Timer _timer;     private TimeSpan _period;     private DateTime _next;      public TimerPlus(TimerCallback callback, object state, TimeSpan dueTime, TimeSpan period)     {         _timer = new Timer(Callback, state, dueTime, period);         _realCallback = callback;         _period = period;         _next = DateTime.Now.Add(dueTime);     }      private void Callback(object state)     {         _next = DateTime.Now.Add(_period);         _realCallback(state);     }      public TimeSpan Period => _period;     public DateTime Next => _next;     public TimeSpan DueTime => _next - DateTime.Now;      public bool Change(TimeSpan dueTime, TimeSpan period)     {         _period = period;         _next = DateTime.Now.Add(dueTime);         return _timer.Change(dueTime, period);     }      public void Dispose() => _timer.Dispose(); } 
like image 156
Samuel Neff Avatar answered Sep 28 '22 11:09

Samuel Neff


I am aware, that the topic is more than 3 years old. However I came across it while tackling exactly the same problem.

Inspired by Samuel Neff, I came up with a WinForms-less solution by extending the standard System.Timers.Timer class:

public class TimerPlus : System.Timers.Timer {     private DateTime m_dueTime;      public TimerPlus() : base() => this.Elapsed += this.ElapsedAction;      protected new void Dispose()     {         this.Elapsed -= this.ElapsedAction;         base.Dispose();     }      public double TimeLeft => (this.m_dueTime - DateTime.Now).TotalMilliseconds;     public new void Start()     {         this.m_dueTime = DateTime.Now.AddMilliseconds(this.Interval);         base.Start();     }      private void ElapsedAction(object sender, System.Timers.ElapsedEventArgs e)     {         if (this.AutoReset)             this.m_dueTime = DateTime.Now.AddMilliseconds(this.Interval);     } } 

I hope it helps.

like image 25
Mike Avatar answered Sep 28 '22 12:09

Mike