System.timers.timer Como ficar tempo permanecendo até a elapitação
-
21-09-2019 - |
Pergunta
Usando C#, como posso conseguir tempo restante (antes que o evento de elapso ocorrer) de um System.Timers.Timer
objeto?
Em outras palavras, digamos que eu defina o intervalo do timer para 6 horas, mas 3 horas depois, quero saber quanto tempo permanece. Como eu conseguiria que o objeto do timer revele esse tempo restante?
Solução
O temporizador embutido não fornece o tempo restante até a decorrer. Você precisará criar sua própria classe que envolva um cronômetro e expõe essas informações.
Algo assim deve funcionar.
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
{
get
{
return _period;
}
}
public DateTime Next
{
get
{
return _next;
}
}
public TimeSpan DueTime
{
get
{
return _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();
}
}
Outras dicas
Estou ciente de que o tópico tem mais de 3 anos. No entanto, me deparei com isso enquanto abordava exatamente o mesmo problema.
Inspirado por Samuel Neff, criei uma solução sem winforms, estendendo a classe Standard System.timers.timer:
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
{
get
{
return (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);
}
}
}
Espero que ajude.
Eu acho que o melhor método é manter o tempo de início em uma variável e depois calcular o tempo decorrido como
TimeSpan t = DateTime.Now - StartTime;