简体   繁体   English

未命中System.Threading.Timer回调

[英]System.Threading.Timer callback not being hit

I have a windows service which, among other things, needs to do some database maintenance every 24 hours. 我有一个Windows服务,除其他外,它需要每24小时进行一些数据库维护。 (SQL express, so can't schedule it inside the database) (SQL Express,因此无法在数据库内部进行调度)

For this I have created a Timer with a callback to the database maintenance method, but it appears to only get hit once (upon creation of the timer, I assume). 为此,我创建了一个带有回调数据库维护方法的计时器,但它似乎只被击中了一次(我认为在创建计时器后)。 I assumed this was due to the timer itself getting out of scope and being GC'd, but none of the sollutions I've tried seem to be working 我认为这是由于计时器本身超出范围并进行了GC处理,但是我尝试过的所有解决方案似乎都无法正常工作

The basic layout of the service is like this: 服务的基本布局如下:

WindowsService.cs: WindowsService.cs:

    protected override void OnStart(string[] args)
    {
        ThreadPool.QueueUserWorkItem(StartServices);
    }

    private void StartServices() { Manager.Start(); }

Manager.cs: 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
  }
}

Obviously this code is severely simplified, but this is pretty much what happens. 显然,此代码已被严格简化,但这几乎就是所发生的事情。 As stated before, I believe GC is the problem, which made me try the following 2 things: 如前所述,我认为GC是问题所在,这使我尝试了以下两件事:

  • Use the constructor Timer(callback), so it will provide a self-reference to the callback. 使用构造函数Timer(callback),因此它将提供对回调的自引用。 However, this would still not prevent it from running out of scope, so that's a no go. 但是,这仍然不会阻止它超出范围,所以这是不可行的。
  • Define the timer as a static variable inside the Manager class. 将计时器定义为Manager类中的静态变量。 This should prevent it from ever being GC'd, but still doesn't appear to have it be called every 24 hours. 应该可以防止它被GC使用,但似乎并没有每24小时调用一次。

Any help in this matter would be greatly appreciated 在这方面的任何帮助将不胜感激

In the end I used a regular System.Timers.Timer which solved my problems. 最后,我使用了常规的System.Timers.Timer解决了我的问题。 Still not sure where I went wrong with the System.Threading.Timer, though. 不过,仍然不确定我System.Threading.Timer出了什么问题。

Since you cannot use the SQL Server agent in SQL Server Express, the best solution is to create a SQL Script, and then run it as a scheduled task. 由于不能在SQL Server Express中使用SQL Server代理,因此最好的解决方案是创建SQL脚本,然后将其作为计划任务运行。

It i easy to verify and mantain, you could have multiple scheduled tasks to fit in with your backup schedule/retention. 我可以轻松地进行验证和维护,您可以安排多个计划任务来适应您的备份计划/保留时间。

The command I use in the scheduled task is: 我在计划任务中使用的命令是:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM