【问题标题】:Multiple Timers on Windows Service Not Firing CorrectlyWindows 服务上的多个计时器未正确触发
【发布时间】:2012-03-30 20:23:37
【问题描述】:

我继承了一项 Windows 服务来增强我的公司。目前,该服务每天在指定的开始时间打印数据库中特定记录的报告。我正在添加一个条件来设置第二个开始时间来运行相同的报告而忽略特定的记录。我遇到的问题是我设置了两个单独的开始时间(通常相隔 15 分钟左右),并且它似乎跳过了第一个开始时间,并且仅在报告文件已经存在时才运行第二个开始时间。

    public partial class Service1 : ServiceBase
{
    Timer t1;
    Timer t2;
    bool Condition;

    public Service1()
    {
        InitializeComponent();
    }
    protected override void OnStart(string[] args)
    {
        t1 = new Timer();
        t1.Interval = (1000 * 60 * 3); // 3 minutes...
        t1.Elapsed += new ElapsedEventHandler(t1_Elapsed);
        t1.AutoReset = true;
        t1.Enabled = true;

        if (Condition) //Condition is an option in the configuration to determine if this timer should even start
        {
            t2 = new Timer();
            t2.Interval = (1000 * 60 * 3); // 3 minutes...
            t2.Elapsed += new ElapsedEventHandler(t2_Elapsed);
            t2.AutoReset = true;
            t2.Enabled = true;
        }
    }
    private void t1_Elapsed(object sender, ElapsedEventArgs e)
    {
        if (File.Exists("FileName1"))
        {
            string CurrentTime = DateTime.Now.ToShortDateString();

            if (CurrentTime == ConfigurationManager.AppSettings["StartTime"].ToString())
            {
                //Print Report
            }
        }
        else
        {
            //Print Report
        }
    }
    private void t2_Elapsed(object sender, ElapsedEventArgs e)
    {
        if (File.Exists("FileName2"))
        {
            string CurrentTime2 = DateTime.Now.ToShortDateString();

            if (CurrentTime2 == ConfigurationManager.AppSettings["StartTime2"].ToString())
            {
                //Print Report 2
            }
        }
        else
        {
            //Print Report 2
        }
    }        
    protected override void OnStop()
    {
        t1.Enabled = false;
        t2.Enabled = false;
    }
}

我不明白为什么会跳过第一个。两者都将检查文件是否存在,如果不存在则打印。下次运行时,第二个报告将在预定时间打印,但第一个被跳过。我似乎无法弄清楚我错过了什么。

【问题讨论】:

  • 你为什么要使用两个计时器呢?将任务分解为单独的方法,并从单个计时器经过的事件中调用这些方法,并在计时器经过的事件中检查您的条件。
  • 旁注,您应该为此使用scheduled tasks。服务 + 计时器 = 设计气味。通过这样做,您可以避免遇到的大部分问题。此外,您比较时间的方式似乎非常错误。你的问题可能就在里面。如果不看到 StartTime 和 StartTime2 就很难判断,因为它们实际上在您的配置文件中。
  • 我最初在一个计时器上将它作为两种不同的方法使用,但我遇到了某种不同的问题,不幸的是,我不记得它是什么了。此后,我对此进行了一些其他更改,因此将其改回可能会起作用。
  • @Will 我曾向某人提到,每个人都建议这应该是一项计划任务,但存在其他人不想处理的凭据问题。但是,我同意你的观点,这更适合走这条路。
  • 尝试通过 try/catch 在 elapsed_handlers 中包装代码并记录错误,也许在第一次进入时引发了一些异常?

标签: c# .net multithreading windows-services timer


【解决方案1】:

您是否有可能使用了错误的计时器? 我记得 .Net 中大约有 2 或 3 种类型的计时器:

System.Timers.Timer

System.Thread.Timer

System.Windows.Forms.Timer

我相信在 Windows 服务中,您应该使用前两个之一,更有可能是 System.Timers.Timer,因为它通过 SynchronizationObject 属性提供线程安全性: System.Timers.Timer vs System.Threading.Timer

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-12-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多