数据库驱动的“计划任务” C# 中的应用程序 - 需要一些关于 cron 语法的建议
对于一个工作项目,我正在执行一项任务,将创建一个 24/7 运行的 C#.NET Windows 服务。该程序本质上只是在不同位置之间移动文件(基于给定的路径和正则表达式)——从/到 HTTP、网络路径和 FTP。管理员将通过 ASP.NET 中的管理页面安排这些作业,其中所有作业都将存储在数据库中。看似最难的部分是安排这些作业 - 安排任务在某一天的某个时间运行非常简单,但它也需要足够健壮,以允许任务每天、每个工作日、每个特定的一天运行当月,甚至每隔几秒/分钟。我得出的结论是,存储此调度信息的最简单方法是在数据库中使用 cron 语法 (http://adminschoice.com/crontab-quick-reference)。
该应用程序有一个计时器,每 10 分钟检查数据库是否有更改,但我遇到的主要问题是检索要执行的任务 - 我想一个选择是每 10 分钟简单地检索所有内容,并检查每个单独的行看看它们是否应该被执行。但我觉得这是一种非常低效且技术上懒惰的方式 - 你们会怎么做?
我知道 Windows 计划任务会是一种更简单的方法,但似乎我的老板不希望这样。
预先感谢任何可以提供一些提示/建议的人。
For a work project I am undertaking a task that will see me create a C#.NET Windows Service that will run 24/7. The program will essentially simply move files (based on a given path and a regex) between various locations - from/to HTTP, Network Paths and FTP. The administrator will schedule these jobs via an administration page in ASP.NET, where all jobs will be stored in a database. Seemingly the hardest part is scheduling these jobs - it is very simple to schedule tasks to run on a certain day at a certain time, but it also needs to be robust enough to allow tasks to run every day, every week day, every certain day of the month, or even every few seconds/minutes. I have concluded that the easiest way to store this scheduling information would be to use cron syntax (http://adminschoice.com/crontab-quick-reference) in the database.
The application has a timer to check the database for changes every 10 minutes, but the main issue I have is going about retrieving the tasks to be performed - I guess one option would be to simply retrieve everything every 10 minutes, and check each individual row to see if they are due to be performed. But I feel this is a very inefficient and technically lazy way - how would you guys go about this?
I know that Windows Scheduled Tasks would be a much easier way, but seems like my boss doesn't want that.
Thanks in advance to anyone that can offer some tips/advice.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
如果您需要跟踪的任务数量并不大,您可以在内存中维护所有任务的优先级队列。节点将包含记录密钥(来自数据库)和计算的下一个更新日期/时间。
当程序启动时,从数据库中读取每条记录并构建优先级队列。构建队列后,查看第一个项目的日期并设置一个计时器以在该时间唤醒。当计时器唤醒时,执行当前到期的所有任务,重新安排它们的下一个更新日期/时间,找到下一个需要更新的项目,并设置一个计时器以在该时间到来时唤醒。
为了处理修改,您也可以让修改内容的 Web 应用程序通知您的服务。您必须取消现有计时器并重新安排,但除了启动时之外,您不必读取整个数据库。
也就是说,我同意@Oded:说服你的老板使用 Windows 计划任务。如果他不喜欢该界面,您可以让您的 Web 应用程序(或 Web 应用程序与之通信的服务)与 Windows 任务计划程序 API 进行通信。 Codeplex 有一个包装器:http://taskscheduler.codeplex.com/
If the number of tasks you have to keep track of isn't huge, you could maintain a priority queue of all the tasks in memory. The nodes would contain the record key (from the database) and the computed next update date/time.
When the program starts up, read every record from the database and construct your priority queue. Once the queue is constructed, look at the first item's date and set a timer to wake up at that time. When the timer wakes up, execute all tasks that are currently due, reschedule them for their next update date/time, find the next item that needs updating and set a timer to wake up when that time arrives.
To handle modifications, you can have the web application that modifies things to notify your service, too. You'd have to cancel the existing timer and re-schedule, but you wouldn't have to read the entire database except at startup.
That said, I agree with @Oded: convince your boss to use Windows Scheduled Tasks. If he doesn't like that interface, you can have your web app (or a service that the web app communicates with) talk to the Windows Task Scheduler API. Codeplex has a wrapper: http://taskscheduler.codeplex.com/
看看 Quartz.NET - 几乎完全符合您的要求。您也可以使用 Cron 表达式 来安排它。
如果您在数据库中存储了有关每个作业的足够信息,则每次服务启动时您都可以创建一个作业。您可以定期轮询更改并更新作业规则。
将其托管在 Windows 服务中是一个很好的方法 - 允许您监视其运行并提供标准机制以在其失败时重新启动它(net start xxx)等。比计划任务好得多。
Have a look at Quartz.NET - pretty much does exactly what you want. You can schedule it using Cron expressions too.
If you store the enough information about each job in the database, you'll be able to create a job each time your service starts. You can poll for changes periodically and update the job's rules.
Hosting this in a windows service is a good way to do it - allow you to monitor that its running and provides standard mechanisms to restart it should it fall over (net start xxx) etc. Much better than scheduled tasks.