0

这是我的问题,我正在编写一个 C# 应用程序,该应用程序将登录到远程SQL Server 2008 [准确地说是 Express 版]并定期从数据库表(比如 foo)中获取数据[每次获取 SQL 客户端连接后关闭] .

如何以 60 秒左右的时间间隔定期执行此过程(用户可定义)。??

4

3 回答 3

1

时间间隔为 60 秒左右

60s 比 Windows 任务计划程序的设置要少得多——它可以通过高级设置来完成(每天一次,每分钟重复一次。

一个悬而未决的问题是,如果任务的运行时间超过调度程序间隔,该怎么办?两次运行是否可以重叠?假设它们可以重叠一些简单的东西:

var timer = new System.Threading.Timer(method, null, 
                                       TimeSpan.Zero, // Start now.
                                       TimeSpan.FromSeconds(60));

method类型的委托在哪里TimerCallback:接受一个object 状态null上面传递)并且什么都不返回。

如果您不想在下一个任务被跳过或延迟时允许调用重叠,假设跳过:

var object locker = new object();
var timer = new System.Threading.Timer(_ => {
  bool entered = Monitor.TryEnter(locker);
  try {
    if (entered) {
      method(null);
    }
  } finally {
     if (entered) {
       Monitor.Exit(locker);
     }
  }
},  null, TimeSpan.Zero, TimeSpan.FromSeconds(60));

(再次,method这里是工人代码)。

于 2012-10-30T15:47:33.150 回答
1

而不是System.Threading.Timer我会使用System.Timers.Timerwhich 可以配置为使用AutoReset属性的“一次性”计时器:

System.Timers.Timer sqlTimer = new System.Timers.Timer();
sqlTimer.Interval = 60000; // One minute
sqlTimer.AutoReset = false; // Fire only once
sqlTimer.Elapsed = TimerEvent; // Assign event for timer
sqlTimer.Start(); // Start the timer

在这种情况下,由于计时器只触发一次,您无需担心锁定或同步:

private void TimerEvent(object source, ElapsedEventArgs e)
{
    // Do your SQL-stuff

    // Restart the timer if you want
    sqlTimer.Start();
}

必须注意的是,这个计时器也运行在一个单独的线程中,因此TimerEvent不会在创建计时器的线程的上下文中调用该事件。如果您需要更新任何 UI 元素,了解这一点很重要。

请注意,这不适用于 .NET Compact Framework,因为它不知道System.Timers命名空间 - 在这种情况下,您必须使用 Richard 的解决方案。

于 2012-10-30T16:04:30.250 回答
-1

为什么不使用 SQL Server 代理中的内置调度程序,或者 Windows 中内置的调度程序?为什么要重新发明轮子?

来自MSDN

SQL Server 代理的好处SQL Server 代理使用 SQL Server 来存储作业信息。作业包含一个或多个作业步骤。每个步骤都包含自己的任务,例如备份数据库。

SQL Server 代理可以按计划、响应特定事件或按需运行作业。例如,如果您想在每个工作日下班后备份所有公司服务器,您可以自动执行此任务。将备份安排在周一至周五的 22:00 之后运行;如果备份遇到问题,SQL Server 代理可以记录事件并通知您。

或者看到这个:

是否可以在自己的应用程序中使用 Windows 7 任务调度程序

或者

如何安排 C# Windows 服务每天执行任务?

于 2012-10-30T09:50:15.890 回答