是否有任何原因计时器会自动重置错误,但随后在其经过的事件中重新启动自身

本文关键字:经过 重新启动 事件 计时器 任何原 错误 是否 | 更新日期: 2023-09-27 18:33:33

我刚刚碰到了这段代码,我不明白。是否有理由使用此设计,而不仅仅是使用自动重置 true 重新运行经过的代码?

private readonly Timer Timer = new Timer();
protected override void OnStart(string[] args)
{
    Logger.InfoFormat("Starting {0}.", ServiceName);
    try
    {
        //  If Enabled is set to true and AutoReset is set to false, the Timer raises the Elapsed event only once, the first time the interval elapses.
        Timer.AutoReset = false;
        Timer.Elapsed += Timer_Elapsed;
        Timer.Interval = Settings.Default.ScriptingStatusLifeTime;
        Timer.Start();
    }
    catch (Exception exception)
    {
        Logger.ErrorFormat("An error has occurred while starting {0}.", ServiceName);
        Logger.Error(exception);
        throw;
    }
}
/// <summary>
/// Whenever the Schedule Service time elapses - go to the ScriptingStatus table
/// and delete everything created earlier than 1 hour ago (by default, read from ScriptingStatusLifeTime) 
/// </summary>
private void Timer_Elapsed(object sender, ElapsedEventArgs e)
{
    try
    {
        //  ScriptingStatusLifeTime defaults to 60 minutes.
        DateTime deleteUntil = DateTime.Now.AddMilliseconds(Settings.Default.ScriptingStatusLifeTime * -1);
        Logger.InfoFormat("Clearing all ScriptingStatus entries with ControlDate before: {0}.", deleteUntil);
        RemoteActivator.Create<RemoteScriptingStatus>().DeleteUntil(deleteUntil);
    }
    catch (Exception exception)
    {
        Logger.Error(exception);
    }
    finally
    {
        Timer.Start();
    }
}

此外,我正在此代码中寻找内存泄漏。

我刚刚读了这篇文章:如果自动重置设置为 false,我的计时器会自动释放吗?这似乎意味着我的 Timer 对象需要正确处理。我在当前文件中看不到任何对"处置"的调用。我想知道这个Timer_Elapsed事件是否也引入了泄漏?

是否有任何原因计时器会自动重置错误,但随后在其经过的事件中重新启动自身

据我了解,通过AutoReset true,触发的计时器事件可能会重叠,其中事件执行所需的时间超出了超时值。

例如,超时为 10 秒,但工作负载为 1 分钟。

但是,如果AutoReset为 false,则计时器事件将仅触发一次。您可以在事件中重新启动计时器,计时器可以继续。

在示例中,这意味着计时器可以在 10 秒后触发,但如果事件花费的时间超过 10 秒,则没有重叠,它将在工作完成后重新启动。

这几乎就是我的做法,也是您在示例代码中使用它的方式。

附录:仅当您未设置同步对象时,上述情况才成立,这是因为已发生的事件是在线程池上引发的。如果您设置了一个同步对象,那么我希望锁定会阻止已过的事件,以便一次只能触发一个事件。