Windows服务vs计划任务

Windows服务与重复运行程序的计划任务(例如,每两分钟)有什么优缺点?

更新:

我原来的答案差不多四年了,这个答案已经过时了。 由于TopShelf随着Windows Services的发展而变得容易。 现在你只需要弄清楚如何支持故障转移…

原始答案:

我真的不是Windows调度程序的粉丝。 用户的密码必须在@moodforall中提供,如果有人改变了用户的密码,这很有趣。

Windows调度程序的另一个主要烦恼是交互式运行,而不是后台进程。 当RDP会话期间每20分钟popup15个MS-DOS窗口时,您将自己踢,而不是将它们安装为Windows服务。

无论您select什么,我都推荐您将处理代码从控制台应用程序或Windows服务中分离出来。 然后,您可以select从控制台应用程序调用工作进程并将其挂接到Windows计划程序,或者使用Windows服务。

你会发现安排一个Windows服务并不好玩。 一个相当常见的情况是,您需要定期运行一个长时间运行的进程。 但是,如果您正在处理一个队列,那么您确实不希望同一个工作程序的两个实例处理相同的队列。 因此,您需要pipe理定时器,以确定您的长时间运行的进程是否已运行超过指定的定时器时间间隔,直到现有进程结束,才会再次启动。

写完所有内容之后,你会想,为什么我不使用Thread.Sleep? 这使我可以让当前的线程继续运行,直到完成,然后暂停时间间隔开始,线程进入hibernate状态,在需要的时间之后再次启动。 整齐!

然后,你就可以阅读互联网上的所有build议,有很多专家告诉你这是一个糟糕的编程习惯:

http://msmvps.com/blogs/peterritchie/archive/2007/04/26/thread-sleep-is-a-sign-of-a-poorly-designed-program.aspx

所以你会抓住你的脑袋,想想自己,跆拳道,撤消待审结帐 – >是的,我敢肯定 – >撤消所有今天的工作…..该死的,该死的,该死的….

不过,我喜欢这种模式,即使每个人都认为它是废话:

用于单线程方法的OnStart方法。

protected override void OnStart (string args) { // Create worker thread; this will invoke the WorkerFunction // when we start it. // Since we use a separate worker thread, the main service // thread will return quickly, telling Windows that service has started ThreadStart st = new ThreadStart(WorkerFunction); workerThread = new Thread(st); // set flag to indicate worker thread is active serviceStarted = true; // start the thread workerThread.Start(); } 

代码实例化一个单独的线程并将我们的工作函数附加到它。 然后它启动线程并让OnStart事件完成,以便Windows不认为该服务已挂起。

单线程方法的工作者方法。

 /// <summary> /// This function will do all the work /// Once it is done with its tasks, it will be suspended for some time; /// it will continue to repeat this until the service is stopped /// </summary> private void WorkerFunction() { // start an endless loop; loop will abort only when "serviceStarted" // flag = false while (serviceStarted) { // do something // exception handling omitted here for simplicity EventLog.WriteEntry("Service working", System.Diagnostics.EventLogEntryType.Information); // yield if (serviceStarted) { Thread.Sleep(new TimeSpan(0, interval, 0)); } } // time to end the thread Thread.CurrentThread.Abort(); } 

OnStop方法的单线程方法。

 protected override void OnStop() { // flag to tell the worker process to stop serviceStarted = false; // give it a little time to finish any pending work workerThread.Join(new TimeSpan(0,2,0)); } 

来源: http : //tutorials.csharp-online.net/Creating_a_.NET_Windows_Service%E2%80%94Alternative_1%3a_Use_a_Separate_Thread (Dead Link)

我已经运行了很多年的Windows服务,这对我很有帮助。 我还没有看到人们同意的推荐模式。 只要做你的工作。

这里有一些错误信息。 Windows调度程序是完全有能力在后台运行的任务没有窗口popup,没有密码的要求。 在NT AUTHORITY \ SYSTEM帐户下运行它。 使用这个schtasks开关:

/ ru系统

但是,对于访问networking资源,最佳做法是使用单独的非过期密码策略的服务帐户。

编辑

根据您的操作系统和任务本身的要求,使用/ru选项,您可以使用权限低于本地系统的帐户。

从精细的手册 ,

 /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和Server 2008中获得。

在XP和Server 2003中, system是唯一的select。

什么是开始和退出应用程序的开销? 每两分钟一次。 一个服务可能会让系统运行得更为顺利,而不是频繁地执行你的应用程序。

当用户没有login时,这两个解决scheme都可以运行程序,所以没有什么区别。 但是,编写服务比常规的桌面应用程序要复杂一些,但是您可能需要一个单独的GUI客户端,它将通过TCP / IP,命名pipe道等与服务应用程序进行通信。

从用户的POV,我不知道哪个更容易控制。 对于大多数非技术用户来说,服务和计划任务都远远不能实现,即他们甚至不会意识到它们存在,并且可以被configuration/停止/重新安排等等。

“服务”一词与“服务”有共同之处。 预计将始终运行,并“服务”。 任务是一项任务。

angular色扮演。 如果我是另一个操作系统,应用程序或设备,我打电话给一个服务,我期望它运行,我希望得到回应。 如果我(操作系统,应用程序,开发人员)只是需要执行一个孤立的任务,那么我将执行一个任务,但如果我期望进行通信,可能是双向通信,我想要一个服务。 这与两件事情交stream的最有效方式有关,或者是一件想要执行单一任务的事情。

然后是调度方面。 如果你想在特定的时间运行一些东西,安排。 如果你不知道什么时候需要它,或者需要“即时”服务。

我的回答在本质上更具哲理性,因为这与人与人之间的互动和工作方式非常相似。 我们越了解交际的艺术,“实体”理解了他们的angular色,就越容易做出这个决定。

除了所有的理念,当你“快速成型”时,正如我的IT部门经常做的那样,为了维持生计,你必须做任何事情。 一旦原型和概念certificate不成立,通常在早期的规划和发现中,就必须决定哪些是长期可持续性更可靠的。

好的,所以最后,这是高度依赖于很多因素,但希望这提供了洞察力,而不是混淆。

在.NET开发中,我通常先开发一个控制台应用程序,它将运行所有日志输出到控制台窗口。 但是,这仅仅是一个控制台应用程序,当它运行命令参数/console 。 当它没有这个参数运行,它作为一个Windows服务,将保持运行在我自己的自定义编码计划的计时器。

我认为,Windows服务通常用于pipe理其他应用程序,而不是一个长时间运行的应用程序。 或..他们是连续运行重量级的应用程序,如SQL Server,BizTalk,RPC连接,IIS(即使IIS技术上卸载工作到其他进程)。

就个人而言,我比Windows服务更喜欢重复性维护任务和应用程序,例如文件复制/同步,批量电子邮件发送,文件删除或存档,数据更正(当其他解决方法不可用时)。

对于一个项目,我参与了8个或9个Windows服务的开发,但是这些项目在内存中闲置,每个实例的内存消耗20MB或更多。 计划任务将完成他们的业务,并立即释放内存。

  1. 使用正确的权限设置和lockingWindows服务更容易。
  2. 服务更“可见”,意味着每个人(即技术人员)都知道在哪里寻找。

Windows服务不需要任何人login,Windows有停止,启动和logging服务结果的function。

计划任务不要求您学习如何编写Windows服务。

为什么不提供这两个?

在过去,我把“核心”位放在一个库中,并在服务和控制台应用程序中打包给Whatever.GoGoGo()。

每隔两分钟你就会发射一些东西,这样做的可能性不大,例如只是一个“ping”types的函数。 包装不应该包含比单一的方法调用和一些日志logging。

这是一个古老的问题,但我想分享我所面临的。

最近我被要求捕获一个雷达(从一个气象网站)的截图,并保存在服务器每隔10分钟。

这需要我使用WebBrowser。 我通常做Windows服务,所以我决定做这一个服务,但它会不断崩溃。 这是我在事件查看器错误模块path中看到的:C:\ Windows \ system32 \ MSHTML.dll

由于任务紧迫,我的研究和实验的时间非常less,我决定使用一个简单的控制台应用程序,并将其作为一项任务触发,并顺利执行。

我非常喜欢Jon Galloway在Mark Ransom接受的答案中推荐的文章 。

最近服务器上的密码发生了变化,但没有确认我,所有服务都无法执行,因为他们无法login。 因此,在文章中声称,这是一个问题。 我认为Windows服务可能面临同样的问题(如果我错了,请纠正我,我是一个新手)

还有提到的事情,如果使用任务计划程序窗口popup或控制台窗口popup。 我从来没有面对过。 它可能会popup,但至less是非常瞬间的。

Windows服务需要更多的耐心,直到完成。 它有点难debugging和安装。 这是不露面的。 如果您需要每秒钟,每分钟或每小时完成一项任务,则应selectWindows Service。

预定任务很快就被开发出来,并且有一张脸。 如果您需要每天或每周的任务,则可以使用计划任务。