Pregunta ¿Hay alguna razón por la que un temporizador tenga la función AutoReset en falso, pero luego se reinicie durante su evento transcurrido?


Me topé con este código y no lo entiendo. ¿Hay alguna razón para usar este diseño en lugar de solo volver a ejecutar el código transcurrido con AutoReset verdadero?

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();
    }
}

Además, estoy buscando una pérdida de memoria en este código.

Acabo de leer esta publicación: Si el autoreset está configurado en falso, ¿se eliminará mi temporizador automáticamente? lo que parece implicar que mi objeto Timer debe desecharse adecuadamente. No veo ninguna llamada a Dispose en el archivo actual. Me pregunto si este evento Timer_Elapsed también está introduciendo una fuga.


12
2017-10-01 16:18


origen


Respuestas:


Como yo lo entiendo, al tener AutoReset En true, el evento de temporizador que se dispara puede superponerse cuando el tiempo que tarda el evento en ejecutarse va más allá del valor de tiempo de espera.

Por ejemplo, tiempo de espera de 10 segundos, pero una carga de trabajo de 1 minuto.

Sin embargo con AutoReset como falso, el evento del temporizador solo se disparará una vez. Puede reiniciar el temporizador en su evento y el temporizador puede continuar.

En el ejemplo, esto significa que el temporizador puede disparar después de 10 segundos, pero si el evento demora más de 10 segundos, no hay superposición, solo se reiniciará una vez que se complete el trabajo.

Esto es más o menos como lo hago y también cómo lo tienes en tu código de ejemplo.

Apéndice: Lo anterior solo es cierto si no establece un objeto de sincronización, esto se debe a que el evento transcurrido se genera en el grupo de subprocesos. Si configuras un objeto de sincronización, entonces esperaría que bloqueara el evento transcurrido para que solo un evento pueda disparar a la vez.


27
2017-10-01 16:20