1

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

为此,我创建了一个带有数据库维护方法回调的计时器,但它似乎只被命中一次(我假设在创建计时器时)。我认为这是由于计时器本身超出范围并被 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(callback),因此它将提供对回调的自引用。但是,这仍然不能阻止它超出范围,所以这是不行的。
  • 将计时器定义为 Manager 类中的静态变量。这应该可以防止它被 GC,但似乎仍然没有每 24 小时调用一次。

在这件事上的任何帮助将不胜感激

4

2 回答 2

0

最后,我使用了一个常规的 System.Timers.Timer 来解决我的问题。不过,我仍然不确定 System.Threading.Timer 哪里出了问题。

于 2013-02-25T10:34:27.757 回答
0

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

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

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

C:\Program Files\Microsoft SQL Server\90\Tools\Binn\SQLCMD.EXE" -i"c:\path\to\sqlbackupScript.sql
于 2013-02-25T10:35:34.537 回答