如何做到最好?我想要一个在服务器上运行的应用程序在每晚 03:00 触发一个事件。
12 回答
使用 windows 任务调度程序
如果您想在运行应用程序代码时执行此操作(而不是使用任务调度程序),您应该选择一个让您的应用程序睡眠相当长的持续时间(例如,1 小时或 3,600 秒)。您的应用程序循环,并且随着每个睡眠呼叫到期,应用程序会定期检查距离截止时间 (03:00) 还剩多少时间。一旦剩余的睡眠时间低于粗略的间隔时间,它应该被减少到更短的间隔(每次减半,或减少到 10 秒)。继续循环,休眠并减少间隔时间,直到达到目标截止时间。
这可以防止循环过于频繁地唤醒(86,400 1 秒的间隔是多余的),但它也可以防止应用循环因睡眠时间过长而超过目标截止时间。
您可以制作一个间隔为 1 秒的计时器,当计时器响起时,检查是否为 3:00。
这里有两个基本选项。
如果您尝试在现有服务中执行此操作,则可以使用计时器在每晚 3:00 触发自己,并运行您的“任务”。
话虽如此,这通常通过Windows Task Scheduler更好地处理。您只需安排它在每天 3:00 运行一次,而不是让应用程序 24/7 保持活动状态。
编辑:
如果您需要从代码中使用任务计划程序(在另一条评论中提到),这也是可能的。任务计划程序提供了一个API ,用于通过任务计划程序 ( ITaskScheduler )设置单个任务 ( ITask )。
但是,鉴于您正在使用 XP Embedded,您最好使用正常的系统配置功能,并设置一个每天运行一次的任务。在嵌入式系统中,您应该在部署期间有足够的控制权来执行此操作。
您需要在服务中构建它,以确保即使没有人登录机器也能运行,然后有许多不同的方法来确保触发发生。
考虑将System.Timers.Timer
其中设置为与下一个 3:00Interval
之间的差异。DateTime.Now
这是我们编写的服务的简化版本,它每 60 秒运行一次计时器以查看表...您可以更改计时器经过事件以检查时间并然后运行它:
Dim Timer As System.Timers.Timer
Protected Overrides Sub OnStart(ByVal args() As String)
Timer = New System.Timers.Timer(60000)
AddHandler Timer.Elapsed, AddressOf timer_Elapsed
Timer.Start()
End Sub
Protected Overrides Sub OnStop()
Timer2.Stop()
End Sub
Private Sub timer_Elapsed(ByVal pSender As Object, ByVal pargs As System.Timers.ElapsedEventArgs)
'Ensure the tick happens in the middle of the minute
If DateTime.Now.Second < 25 Then
Timer.Interval = 65000
ElseIf DateTime.Now.Second > 35 Then
Timer.Interval = 55000
ElseIf DateTime.Now.Second >= 25 And DateTime.Now.Second <= 35 Then
Timer.Interval = 60000
End If
'Logic goes here
End Sub
显然,如果可以,请像这里其他所有人提到的那样使用任务调度程序。这是执行此操作的首选方式。我只是碰巧有这段代码,所以我想我会发布它以防它对你有帮助。此外,此代码对我们有用,因为我们不知道外部源何时会编辑表格。正如 md5sum 所指出的,将间隔设置为正确的毫秒数将是一种更有效的方法。
这个答案可能有点偏题,但我们经常将CruiseControl.NET用于我们的一些计划任务。这对他们来说并不完美,但如果你想每晚运行一项大工作并且其他代码/结果取决于它,那么它是一个不错的选择。您可以安排它在任何时候运行,如果它工作/失败,就会收到电子邮件。如果它不起作用,请运行其他脚本/代码,在开始之前和之后清理您需要的文件。
不是所有情况的完美解决方案,但对于那些需要它的人来说,它非常强大。我们将它用于我们的一些大数据处理工作,如果它成功/失败,它会向我们所有人发送一封电子邮件,如果第一次失败,它甚至会在 30 分钟后重试。它给你一种很好的模糊感:)
Windows 任务调度程序(由 klausbyskov 建议)或 SQL Server 作业。
编辑:
或者,如果您想要一个动态分配的时间,您可以创建一个 Windows 服务,该服务每 10 分钟轮询一次,并在所需时间执行一些操作。
在 C# 中创建 Windows 服务器相当简单,可以做到这一点。只需确保您已了解安全性和日志记录,因为很难判断它正在(或未)运行时发生了什么。
我在 ASP.NET 应用程序中生成一个线程来执行计划任务。
程序可以通过命令行运行吗?如果是这样,请创建一个 foo.bat 文件,并调用您的程序命令行(非常简单)。
然后使用任务计划程序在每天凌晨 3 点运行 .bat 文件。