定时器以错误的间隔触发

时间:2012-05-09 11:52:29

标签: c# timer

我试图根据这篇文章抽象system.threading.timer: http://www.derickbailey.com/CommentView,guid,783f22ad-287b-4017-904c-fdae46719a53.aspx

但是,似乎计时器正在根据错误的参数

触发

在下面的课程中我们有这一行

timer = new System.Threading.Timer(o => TimerExecute(), null, 1000, 30000);

这应该意味着在开始前等待1秒钟,然后每30秒开火一次

然而,代码每秒都会触发

我做错了什么

 public interface ITimer
    {
        void Start(Action action);
        void Stop();
    }

    public class Timer : ITimer, IDisposable
    {
        private TimeSpan timerInterval;
        private System.Threading.Timer timer;
        private Action timerAction;

        private bool IsRunning { get; set; }

        public Timer(TimeSpan timerInterval)
        {
            this.timerInterval = timerInterval;
        }

        public void Dispose()
        {
            StopTimer();
        }

        public void Start(Action action)
        {
            timerAction = action;
            IsRunning = true;
            StartTimer();
        }

        public void Stop()
        {
            IsRunning = false;
            StopTimer();
        }

        private void StartTimer()
        {
            timer = new System.Threading.Timer(o => TimerExecute(), null, 1000, Convert.ToInt32(timerInterval.TotalMilliseconds));
        }

        private void StopTimer()
        {
            if (timer != null)
            {
                timer.Change(Timeout.Infinite, Timeout.Infinite);
                timer.Dispose();
                timer = null;
            }
        }

        private void TimerExecute()
        {
            try
            {
                StopTimer();
                timerAction();
            }
            finally
            {
                if (IsRunning)
                    StartTimer();
            }
        }
    }

1 个答案:

答案 0 :(得分:3)

每次命中TimerExecute时都会重新启动计时器。并且由于它重新启动良好,它将在1秒后再次触发。所以我会把TimerExecute改写成这个。

此外,您尝试捕获或尝试最终方法,确保您实际捕获问题并以某种方式处理它们,而不是忽略它。

private void TimerExecute()
    {
        try
        {
            timerAction();
        }
        catch
        {
            //todo
        }
    }