运行Windows服务时计时器被触发两次

时间:2016-06-30 15:21:15

标签: c# timer duplicates

当服务运行时,程序运行两次。平均运行时间为10分钟。

private void InitializeTimer()
{
    var confcontr = new ConfigurationController();
    var config = confcontr.ReadConfiguration();

    try
    {
        if (serviceTimer != null)
        {
            serviceTimer.AutoReset = true;

            Articles art = new Articles(config);

            //Conexion a a los articulos de BD para obtener parametros de iniciación 
            serviceTimer.Interval = Convert.ToDouble(60*1000)* art.Parameter();

            //Se especifica cada que tanto tiempo se ejecuta el servicio
            serviceTimer.Enabled = true;
            serviceTimer.Elapsed += serviceTimer_Elapsed;
        }
    }
    catch (Exception ex)
    {
       Log.Instance.WriteToLog(ex.Message + ex.StackTrace + "initializetimer");
    }
}

这是我打电话的方法

protected void serviceTimer_Elapsed(object sender, ElapsedEventArgs e)
{
    var artcont = new ArticulosController();
    artcont.EjecutarArticulo();
}

2 个答案:

答案 0 :(得分:0)

计时器将通过使用ThreadPool线程引发事件来异步执行Elapsed事件,因此它可以重叠。

取而代之的是关闭AutoReset并尝试以下内容:

protected void serviceTimer_Elapsed(object sender, ElapsedEventArgs e)
{
    var artcont = new ArticulosController();
    artcont.EjecutarArticulo();

    ((Timer)sender).Start();
}

这将在当前Elapsed事件结束后重新启动计时器。

答案 1 :(得分:0)

我会重写你的方法来构造计时器。没有任何保护的事件订阅可能会多次订阅。当您在类之外使用代码或其他开发人员使用它时,尤其如此。作为替代方案,您还可以放置一个isInitialzed变量。如果需要线程安全,请使用锁定。如果需要保护其他进程,请使用互斥锁。如果Elapsed方法长时间运行,请停止计时器并在完成时重新启动它,这样事件就不会“堆积”。在初始化期间,在添加订阅后启动计时器。

private void InitializeTimer()
{
    var confcontr = new ConfigurationController();
    var config = confcontr.ReadConfiguration();

    try
    {
        if (serviceTimer == null)
        {
            serviceTimer = new System.Timers.Timer();

            serviceTimer.AutoReset = true;

            Articles art = new Articles(config);

            //Conexion a a los articulos de BD para obtener parametros de iniciación 
            serviceTimer.Interval = Convert.ToDouble(60 * 1000) * art.Parameter();

            //Se especifica cada que tanto tiempo se ejecuta el servicio
            serviceTimer.Elapsed += serviceTimer_Elapsed;
            serviceTimer.Enabled = true;
        }
    }
    catch (Exception ex)
    {
        Log.Instance.WriteToLog(ex.Message + ex.StackTrace + "initializetimer");
    }
}

protected void serviceTimer_Elapsed(object sender, ElapsedEventArgs e)
{
    serviceTimer.Enabled = false;

    try
    {
        var artcont = new ArticulosController();
        artcont.EjecutarArticulo();
    }
    catch (Exception ex)
    {
        Log.Instance.WriteToLog(ex.Message + ex.StackTrace + "serviceTimer_Elapsed");
    }

    serviceTimer.Enabled = true;
}