System.Threading.Timer回调未被命中

时间:2013-02-25 09:14:42

标签: c# .net timer windows-services

我有一个Windows服务,除其他外,需要每24小时进行一次数据库维护。 (SQL express,所以不能在数据库中安排它)

为此,我创建了一个带有数据库维护方法回调的Timer,但它似乎只被命中一次(在创建定时器时,我假设)。 我认为这是由于计时器本身超出范围并且是GC'd,但我尝试过的解决方案似乎都没有工作

服务的基本布局如下:

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(回调),因此它将提供一个 自我引用回调。但是,这仍然无法阻止 它超出了范围,所以这是不行的。
  • 将计时器定义为 Manager类中的静态变量。这个应该阻止它 来自GC'd,但似乎仍然没有被称为 每24小时一次。

非常感谢任何有关此事的帮助

2 个答案:

答案 0 :(得分:0)

最后我使用了常规的System.Timers.Timer来解决我的问题。 但仍不确定我在System.Threading.Timer出错的地方。

答案 1 :(得分:0)

由于您无法在SQL Server Express中使用SQL Server代理,因此最佳解决方案是创建SQL脚本,然后将其作为计划任务运行。

我很容易验证和维护,您可以有多个计划任务以适应您的备份计划/保留。

我在计划任务中使用的命令是:

C:\Program Files\Microsoft SQL Server\90\Tools\Binn\SQLCMD.EXE" -i"c:\path\to\sqlbackupScript.sql