无法保持计时器处于活动状态的windows服务

本文关键字:活动状态 windows 服务 计时器 | 更新日期: 2024-10-22 15:10:19

我为我的服务器制作了一个windows服务。。。

我需要每分钟检查一下我的SQL数据库中是否有一些新信息。

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

它是这样的:

    • 正在启动服务
    • 设置带间隔的计时器
    • 正在完成并退出服务<--我想让它活着

正如你所看到的,服务退出,我希望Windows服务每分钟都能不停地运行。。。。

我可以在事件查看器中看到"服务成功启动。"answers"Service成功停止"

我该怎么办

p.S:我认为Timer应该在没有出口的情况下工作。。。或者我可能错了?

代码:

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

警报时间:

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....
    }
}

无法保持计时器处于活动状态的windows服务

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

试试这个:

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方法。

您需要将AlertTimer实例存储在将持续服务生命周期的东西中(例如,在TaoTimer内声明为字段的List<AlertTimer>中。

只有在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对象也是可收集的。