【发布时间】:2013-02-25 09:14:41
【问题描述】:
我有一个 Windows 服务,除其他外,它需要每 24 小时进行一次数据库维护。 (SQL express,所以不能在数据库里面调度)
为此,我创建了一个带有数据库维护方法回调的计时器,但它似乎只被命中一次(我假设在创建计时器时)。 我认为这是由于计时器本身超出范围并被 GC 处理,但我尝试过的所有解决方案似乎都不起作用
服务的基本布局是这样的:
WindowsService.cs:
protected override void OnStart(string[] args)
{
ThreadPool.QueueUserWorkItem(StartServices);
}
private void StartServices() { Manager.Start(); }
Manager.cs:
public class Manager
{
private static Timer MaintenanceTimer;
public static void Start()
{
MaintenanceTimer = new Timer(DoMaintenance);
MaintenanceTimer.Change(new TimeSpan(0), new TimeSpan(24,0,0,0)); //I use 1 minute for testing
}
}
显然,这段代码被严重简化了,但这几乎就是发生的事情。 如前所述,我认为 GC 是问题所在,这让我尝试了以下两件事:
- 使用构造函数Timer(callback),所以它会提供一个 对回调的自我引用。但是,这仍然无法阻止 它不会超出范围,所以这是不行的。
- 将定时器定义为 Manager 类中的静态变量。这应该阻止它 从曾经被GC'd,但似乎仍然没有被调用 每 24 小时一次。
在这件事上的任何帮助将不胜感激
【问题讨论】:
-
失败:查找 GC.KeepAlive()
-
DoMaintenance 中会发生什么?是否有可能发生异常?这种行为是否在您的测试中发生?
-
@MitchWheat 我不是,虽然我假设这个建议,但我觉得这有点矫枉过正。我也很好奇它失败的原因。关于您的第二条评论: KeepAlive() 是否会阻止垃圾收集直到您发表声明?这些都是 void 方法,所以我不认为这有什么好处(尽管我可能在这里错了)
-
见stackoverflow.com/questions/4962172/…。你能用
System.Timers.Timer代替System.Timers.Timer吗
标签: c# .net timer windows-services