使Timer无法保持Windows服务

时间:2013-12-16 15:31:39

标签: c# timer windows-services

我为我的服务器制作了一个Windows服务...

如果我的SQL数据库中有新信息,我需要检查每一分钟。

所以我创建了一个Windows服务,创建一个间隔为1分钟的Timer。 但Windows服务设置计时器并结束运行。

就是这样:

    • 开始服务
    • 设置定时器
    • 完成和退出服务< - 我希望保持活力
  1. 正如您可以看到服务出口,我希望Windows服务每分钟运行一次而不会停止....

    我可以在事件查看器中看到“服务已成功启动”。并且“服务已成功停止。”

    我该怎么办?

    P.S:我以为Timer应该退出......或者我可能错了吗?

    CODE:

    Windows服务:

    static void Main(string[] args)
            {
                try
                {
                    Utils.SetConfigFile();
                    var ServiceToRun = new TaoTimer();
                    ServiceToRun.Start(); 
                }
                catch (Exception ex)
                {
                    EventLog.WriteEntry("Application", ex.ToString(), EventLogEntryType.Error);
                }
             }
    

    TaoTimer:

    public partial class TaoTimer : ServiceBase
    {
        List<TimerModel> timerList;
        public TaoTimer()
        {
            InitializeComponent();
        }
        protected override void OnStart(string[] args)
        {
            EventLog.WriteEntry("Started");
        }
        public void SetTimer(TimerModel timerModel)
        {
            int minute = 1000 * 60;
            try
            {
                AlertTimer at = new AlertTimer(timerModel, minute);
                at.Start();
            }
            catch
            {
    
            }
        }
        protected override void OnStop()
        {
            EventLog.WriteEntry("Stopped");
        }
        protected override void OnPause()
        {
            EventLog.WriteEntry("Paused");
        }
        protected override void OnContinue()
        {
            EventLog.WriteEntry("Continuing");
        }
        protected override void OnShutdown()
        {
            EventLog.WriteEntry("ShutDowned");
        }
        public void Start()
        {
            SetTimerList();
        }
        protected void SetTimerList()//Read Config from xml and start the timer
        {
            XElement root = XElement.Load(@"C:\TaoTimer\Data.xml");
            timerList = new List<TimerModel>(from d in root.Descendants("Timer")
                                             select new TimerModel(
                               d.Element("Id").Value.ToString(),
                               d.Element("Name").Value.ToString(),
                               d.Element("InterVal").Value.ToString(),
                               d.Element("TimeFormat").Value.ToString(),
                               d.Element("Day").Value.ToString(),
                               d.Element("TimeStamp").Value.ToString()));
            timerList.ForEach(i => SetTimer(i));
        }
    }
    

    AlertTimer:

    public class AlertTimer
    {
        static System.Timers.Timer aTimer = new System.Timers.Timer();
        public AlertTimer(TimerModel timerModel, int milliseconds)
        {
            aTimer.Elapsed += new ElapsedEventHandler((sender, e) => OnTimedEvent(sender, e, timerModel));
            aTimer.Interval = milliseconds;
        }    
        public void Start()
        {
            aTimer.Enabled = true;
        }
        public static void OnTimedEvent(object source, ElapsedEventArgs e, TimerModel timerModel)
        {
            getAbsenceContacts.Start();<-- NEVER GETS HERE....
        }
    }
    

2 个答案:

答案 0 :(得分:1)

您实际上并没有开始提供服务。您正在调用名为Start的方法,该方法不是Windows Service类层次结构的一部分,它只是您定义的方法。您的方法运行并完成,因此服务退出。

试试这个:

static void Main(string[] args)
    {
        try
        {
            Utils.SetConfigFile();
            ServiceBase[] ServicesToRun;
            ServicesToRun = new ServiceBase[] 
            { 
                new TaoTimer() 
            };
            ServiceBase.Run(ServicesToRun);
        }
        catch (Exception ex)
        {
            EventLog.WriteEntry("Application", ex.ToString(), EventLogEntryType.Error);
        }
     }

public partial class TaoTimer : ServiceBase
{
    ...
    protected override void OnStart(string[] args)
    {
        SetTimerList();
        EventLog.WriteEntry("Started");
    }
    ....
}

并完全从TaoTimer中删除Start方法。

答案 1 :(得分:1)

您需要将AlertTimer个实例存储在服务生命周期内的某些内容中(例如,在List<AlertTimer>内声明为TaoTimer的字段{/ 1}}。

Timer的文档中,实际上只提到计时器本身并不会阻止自己被垃圾收集。例子说:

    // Normally, the timer is declared at the class level, 
    // so that it stays in scope as long as it is needed. 
    // If the timer is declared in a long-running method,   
    // KeepAlive must be used to prevent the JIT compiler  
    // from allowing aggressive garbage collection to occur  
    // before the method ends. You can experiment with this 
    // by commenting out the class-level declaration and  
    // uncommenting the declaration below; then uncomment 
    // the GC.KeepAlive(aTimer) at the end of the method. 
    //System.Timers.Timer aTimer; 

现在,虽然您的计时器的AlertTimer类内部的类级别声明,但没有任何东西可以阻止AlertTimer个实例被收集。并且GC只保留可传递的可用内容。一旦AlertTimer实例可收集,您的Timer对象也是如此。