【问题标题】:System.Timers.Timer How to get the time remaining until ElapseSystem.Timers.Timer 如何获取到 Elapse 的剩余时间
【发布时间】:2011-01-17 17:21:25
【问题描述】:

使用 C#,我如何从 System.Timers.Timer 对象获取剩余时间(在 elapse 事件发生之前)?

换句话说,假设我将计时器间隔设置为 6 小时,但 3 小时后,我想知道还剩多少时间。如何让计时器对象显示剩余时间?

【问题讨论】:

    标签: c# timer windows-services elapsedtime system.timers.timer


    【解决方案1】:

    内置计时器不提供剩余时间,直到过去。您需要创建自己的类来包装计时器并公开此信息。

    这样的事情应该可以工作。

    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();
    }
    

    【讨论】:

    • 超出了通话范围,但检查了您的努力。谢谢,你很善良。我已经有一个方法可以计算应该剩余多少时间,但想用实际计时器对象本身的输出来确认它。糟糕的是,它不是天生提供的。
    • 是的,他也写得这么快。令人印象深刻。
    • Samuel,你能提供这个类的用法吗?我不确定如何将参数传递给您的构造函数。
    • @HeseinBurg TimerPlusTimer 的直接替代品(这意味着无论您使用Timer,您都可以按原样使用TimerPlus)。它具有相同的功能和 API。添加的是Next 属性,它将始终返回下次触发的DateTime
    【解决方案2】:

    我知道,这个话题已经超过 3 年了。但是我在处理完全相同的问题时遇到了它。

    受 Samuel Neff 的启发,我通过扩展标准 System.Timers.Timer 类提出了一个无需 WinForms 的解决方案:

    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);
        }
    }
    

    希望对你有帮助。

    【讨论】:

      【解决方案3】:

      我想最好的方法是将开始时间保存在一个变量中,然后将经过的时间计算为

      TimeSpan t = DateTime.Now - StartTime;
      

      【讨论】:

      • 我同意。但是,必须检查山姆的努力;他写了一堂课来帮助我。超级亲切。谢谢你们。
      猜你喜欢
      • 2016-07-10
      • 1970-01-01
      • 1970-01-01
      • 2018-05-01
      • 2017-10-22
      • 2021-10-26
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多