14

我只是碰到了这段代码,我不明白。是否有理由使用这种设计,而不是仅仅使用 AutoReset 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 对象需要正确处理。我在当前文件中没有看到任何对 Dispose 的调用。我想知道这个 Timer_Elapsed 事件是否也引入了泄漏?

4

1 回答 1

36

据我了解,由于必须AutoReset为真,被触发的计时器事件可能会在事件执行时间超过超时值的地方重叠。

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

但是,如果设置AutoReset为 false,则计时器事件只会触发一次。您可以在您的事件中重新启动计时器并且计时器可以继续。

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

这几乎就是我的做法,也是你在示例代码中的做法。

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

于 2013-10-01T16:20:52.170 回答