2013-02-25 34 views
1

我有一个Windows服务,其中包括,需要每24小时进行一次数据库维护。 (SQL Express,所以不能在数据库中安排它)System.Threading.Timer回调没有被击中

为此我创建了一个回调数据库维护方法的计时器,但它似乎只被命中一次(创建计时器后,我承担)。 我认为,这是由于定时器本身走出的范围和被GC'd,但没有我试过sollutions似乎是工作

服务的基本布局是这样的:

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是一个问题,这让我试试以下两两件事:

  • 使用构造定时器(回调),因此它会提供一个 自我参照回调。然而,这仍然不会阻止 它超出范围,所以这是不行的。
  • 将定时器定义为 Manager类中的静态变量。这应该阻止它从以前GC'd ,但似乎并没有被称为 每24小时。

在这个问题上的任何帮助,将不胜感激

+0

你意识到:http://www.codeproject.com/Articles/15407/SQL-Agent-A-Job-Scheduler-Framework ? – 2013-02-25 09:17:33

+0

失败:lookup GC.KeepAlive() – 2013-02-25 09:18:18

+0

DoMaintenance中会发生什么?是否有可能发生异常?这种行为是否发生在您的测试中? – 2013-02-25 09:18:39

回答

0

在我用了一个普通System.Timers.Timer这解决了我的问题到底。 尽管如此,仍然不确定我在哪里出错了System.Threading.Timer。

0

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

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

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

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