Why does System.Timer.Timer still fire events when Enabled is set to false?

前端 未结 5 606
佛祖请我去吃肉
佛祖请我去吃肉 2021-01-12 04:35

I have attempted to create a derived class of Timer that allows for a \'Pause\' latch to be set to keep the worker thread from reactivating the timer. However, Elapsed event

5条回答
  •  余生分开走
    2021-01-12 05:25

    Relevant document, System.Timers.Timer.Interval

    Note If Enabled and AutoReset are both set to false, and the timer has previously been enabled, setting the Interval property causes the Elapsed event to be raised once, as if the Enabled property had been set to true. To set the interval without raising the event, you can temporarily set the AutoReset property to true.

    The recommended solution of setting AutoReset to true does not solve the problem because there is an undocumented behavior of setting AutoReset to true during an event handler also allowing for an event to be fired.

    The solution seems to be to build out the derived object to the point where you can keep any of the apparently many ways that an event can be fired again from happening.

    Below is the implementation that I ended with.

    public class PauseableTimer : Timer
    {
        private bool _paused;
        public bool Paused
        {
            get { return _paused; }
            set 
            { 
                Interval = _interval;
                _paused = value;
            }
        }
    
        new public bool Enabled
        {
            get
            {
                return base.Enabled;
            }
            set
            {
                if (Paused)
                {
                    if (!value) base.Enabled = false;
                }
                else
                {
                    base.Enabled = value;
                }
            }
        }
    
        private double _interval;
        new public double Interval
        {
            get { return base.Interval; }
            set
            {
                _interval = value;
                if (Paused){return;}
                if (value>0){base.Interval = _interval;}
            }
        }
    
        public PauseableTimer():base(1){}
    
        public PauseableTimer(double interval):base(interval){}
    }
    

提交回复
热议问题