未命中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.Threading.Timer回调

最后我使用了一个常规的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