无法保持计时器处于活动状态的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....
}
}
您实际上并没有启动您的服务。您正在调用一个名为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
对象也是可收集的。