执行时间超过span时的计时器行为?

kat*_*tit 19 .net c# windows-services timer

我正在编写Windows服务,每隔几分钟就会处理一些"东西".

这是一些代码:

public Service()
        {
            this.InitializeComponent();
            this.ServiceName = Name;
            this.CanPauseAndContinue = true;
            this.CanShutdown = true;

            this.eventLog.Source = Name;

            // initialize timer
            this.timer.Elapsed += this.TimerElapsed;
        }

        private void TimerElapsed(object sender, ElapsedEventArgs e)
        {
            eventLog.WriteEntry("Starting syncronization...", EventLogEntryType.Information);

            if (this.processor.PrepareToRun())
            {
                this.processor.Run();
            }
        }
Run Code Online (Sandbox Code Playgroud)

我想知道如果this.processor.Run()需要很长时间会发生什么,下一次TimerElapsed活动会被提出?它会跳过吗?完成后会等待并尽快运行吗?我应该考虑这些场景和代码吗?

我正在使用 System.Timers.Timer

编辑:

private void TimerElapsed(object sender, ElapsedEventArgs e)
        {
            eventLog.WriteEntry("Starting syncronization...", EventLogEntryType.Information);

            try
            {
                this.timer.Stop();
                if (this.processor.PrepareToRun())
                {
                    this.processor.Run();
                }
            }
            catch (Exception ex)
            {
                LoggingAndNotifications.LogAndNotify(ex);

            }
            finally
            {
                this.timer.Start();
            }
        }
Run Code Online (Sandbox Code Playgroud)

编辑2

public Service()
        {
            this.InitializeComponent();
            this.ServiceName = Name;
            this.CanPauseAndContinue = true;
            this.CanShutdown = true;

            this.eventLog.Source = Name;

            // initialize timer
            this.timer.AutoReset = false;
            this.timer.Elapsed += this.TimerElapsed;
        }

        private void TimerElapsed(object sender, ElapsedEventArgs e)
        {
            eventLog.WriteEntry("Starting syncronization...", EventLogEntryType.Information);

            try
            {
                if (this.processor.PrepareToRun())
                {
                    this.processor.Run();
                }
            }
            catch (Exception ex)
            {
                LoggingAndNotifications.LogAndNotify(ex);
                throw;
            }
            finally
            {
                this.timer.Start();
            }
        }
Run Code Online (Sandbox Code Playgroud)

Jon*_*nna 14

它会在另一个线程上再次调用它.

根据操作的性质,您可能需要:

  1. 忽略这一点,如果调用的代码对多个同时调用是安全的,那么这可能没问题.当然,你必须知道这很好.
  2. 锁定定时器触发的操作.请注意,您最终可能会有许多待处理操作的队列,这非常糟糕.
  3. 锁定定时器触发的操作,尝试获取超时为零的锁定,如果失败则跳过它 - 从最后一次开始仍有一个线程.
  4. 将计时器作为一次性计时器,在每次通话结束时重新启动.

  • 停止计时器无济于事,如果进程中存在大量活动TP线程,则可以延迟Elapsed事件处理程序调用.将AutoReset属性设置为false. (5认同)