windows服务与重复运行程序(例如每两分钟)的计划任务的优缺点是什么?
发布于 2009-11-17 04:39:18
更新:
比我最初的答案晚了将近四年,而这个答案已经非常过时了。自从 问世以来,Windows Services的开发变得很容易。现在您只需要弄清楚如何支持故障转移...
原始答案:
我真的不是Windows Scheduler的粉丝。正如@moodforall上面指出的那样,必须提供用户的密码,当有人更改该用户的密码时,这很有趣。
Windows Scheduler的另一个主要问题是它以交互方式运行,而不是作为后台进程运行。在RDP会话期间,当每隔20分钟弹出15个MS-DOS窗口时,您会因为没有将它们安装为windows服务而感到痛心。
无论您选择哪种方式,我都建议您将处理代码与控制台、应用程序或Windows服务分离到不同的组件中。然后,您可以选择是从控制台应用程序调用工作进程并将其挂钩到Windows Scheduler,还是使用Windows服务。
您会发现调度Windows服务并不有趣。一个相当常见的场景是,您希望定期运行一个长时间运行的进程。但是,如果您正在处理一个队列,那么您确实不希望同一个worker的两个实例处理同一个队列。因此,您需要管理计时器,以确保如果长时间运行的进程的运行时间超过指定的计时器间隔,则在现有进程完成之前,它不会再次启动。
在写完所有这些之后,你会想,为什么我不直接使用Thread.Sleep呢?这允许我让当前线程保持运行,直到它结束,然后暂停间隔开始,线程进入睡眠状态,并在所需时间之后再次启动。干净利落!
然后你在互联网上阅读所有的建议,有很多专家告诉你这是多么糟糕的编程实践:
http://msmvps.com/blogs/peterritchie/archive/2007/04/26/thread-sleep-is-a-sign-of-a-poorly-designed-program.aspx
所以你会抓挠你的头并对自己说,->,Undo Pending Checkouts ->是的,我确定WTF会撤消今天的所有工作。该死,该死,该死...
然而,我确实喜欢这个模式,即使每个人都认为它是垃圾:
单线程方法的
OnStart方法。
protected override void OnStart (string args) { //创建工作线程;这将在我们启动它时调用WorkerFunction //。//因为我们使用的是单独的工作线程,所以主服务//线程会快速返回,告诉Windows服务已经启动ThreadStart st = new ThreadStart(WorkerFunction);workerThread = new Thread(st);//设置工作线程处于活动状态的标志serviceStarted = true;//启动线程workerThread.Start();}
该代码实例化了一个单独的线程,并将worker函数附加到该线程。然后它启动线程并让OnStart事件完成,这样Windows就不会认为服务挂起了。
单线程方法的辅助方法。
/此函数将完成所有工作/一旦完成任务,将暂停一段时间;/将继续执行此操作,直到停止服务/私有void WorkerFunction() { //开始死循环;仅当"serviceStarted“// serviceStarted= false while (serviceStarted) { //做某事//为简单起见,此处省略了异常处理时,循环才会中止(”服务工作“,EventLog.WriteEntry (serviceStarted) {Thread.Sleep( TimeSpan(0,serviceStarted,0));}} //线程结束时间Thread.CurrentThread.Abort();}
单线程方法的OnStop方法。
protected override void OnStop() { //通知工作进程停止serviceStarted =false的标志;//给它一点时间来完成任何挂起的工作workerThread.Join( TimeSpan(0,2,0));}
来源:http://tutorials.csharp-online.net/Creating_a_.NET_Windows_Service%E2%80%94Alternative_1%3a_Use_a_Separate_Thread (死链)
多年来,我已经运行了很多这样的Windows服务,它对我来说很有效。我还没有看到人们一致认可的推荐模式。做对你有用的事就行了。
发布于 2010-05-24 12:22:30
这里有些错误的信息。Windows Scheduler完全能够在后台运行任务,而不会弹出窗口,也不需要密码。在NT AUTHORITY\SYSTEM帐户下运行它。使用此schtask开关:
/ru系统
但是,对于访问网络资源,最佳实践是使用具有单独的非过期密码策略的服务帐户。
编辑
根据您的操作系统和任务本身的要求,您可以将权限低于本地系统的帐户与/ru选项一起使用。
从优秀的manual,
/RU username
A value that specifies the user context under which the task runs.
For the system account, valid values are "", "NT AUTHORITY\SYSTEM", or "SYSTEM".
For Task Scheduler 2.0 tasks, "NT AUTHORITY\LOCALSERVICE", and
"NT AUTHORITY\NETWORKSERVICE" are also valid values.Task Scheduler 2.0可从Vista和Server2008获得。
在XP和Server2003中,system是唯一的选项。
发布于 2008-12-23 23:03:52
启动和退出应用程序的开销是多少?每两分钟是相当常见的。与如此频繁地执行应用程序相比,服务可能会让系统运行得更流畅。
这两种解决方案都可以在用户未登录时运行程序,因此没有区别。然而,编写服务比常规的桌面应用程序要复杂得多--您可能需要一个单独的GUI客户端,该客户端将通过TCP/IP、命名管道等与服务应用程序通信。
从用户的观点来看,我想知道哪个更容易控制。对于大多数非技术用户来说,服务和计划任务都是遥不可及的,也就是说,他们甚至不会意识到它们的存在,可以配置/停止/重新调度等等。
https://stackoverflow.com/questions/390307
复制相似问题