未命中System.Threading.Timer回调
本文关键字:Timer 回调 Threading System | 更新日期: 2023-09-27 18:01:01
我有一个windows服务,它需要每24小时进行一次数据库维护。(SQL express,因此无法在数据库中安排(
为此,我创建了一个带有对数据库维护方法的回调的Timer,但它似乎只命中一次(我认为在创建计时器时(。我认为这是由于计时器本身超出了范围并被GC控制,但我尝试过的解决方案似乎都不适用于
服务的基本布局如下:
WindowsService.cs:
protected override void OnStart(string[] args)
{
ThreadPool.QueueUserWorkItem(StartServices);
}
private void StartServices() { Manager.Start(); }
经理.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(回调(,因此它将提供回调的自引用。然而,这仍然不能阻止它不会超出范围,所以这是不可能的
- 将计时器定义为Manager类中的静态变量。这应该防止它从被GC选中,但似乎仍然没有被调用每24小时
在这方面的任何帮助都将不胜感激
最后我使用了一个常规的System.Timers.Timer,它解决了我的问题。不过,我仍然不确定System.Threading.Timer哪里出了问题。
由于不能在SQL Server Express中使用SQL Server代理,因此最好的解决方案是创建一个SQL脚本,然后将其作为计划任务运行。
它很容易验证和维护,您可以有多个计划任务来适应您的备份时间表/保留期。
我在计划任务中使用的命令是:
C:'Program Files'Microsoft SQL Server'90'Tools'Binn'SQLCMD.EXE" -i"c:'path'to'sqlbackupScript.sql