Windows 服务与计划任务 [英] windows service vs scheduled task

查看:44
本文介绍了Windows 服务与计划任务的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

What are the cons and pros of windows services vs scheduled tasks for running a program repeatedly (e.g. every two minutes)?

推荐答案

更新:

在我最初的答案之后将近四年,这个答案已经过时了.自从 TopShelf 出现后,Windows 服务的开发变得容易了.现在您只需要弄清楚如何支持故障转移...

Nearly four years after my original answer and this answer is very out of date. Since TopShelf came along Windows Services development got easy. Now you just need to figure out how to support failover...

原答案:

我真的不是 Windows 调度程序的粉丝.必须提供用户的密码,正如 @moodforall 上面指出的那样,当有人更改该用户的密码时,这很有趣.

I'm really not a fan of Windows Scheduler. The user's password must be provided as @moodforall points out above, which is fun when someone changes that user's password.

Windows 调度程序的另一个主要烦恼是它以交互方式运行,而不是作为后台进程运行.当 RDP 会话期间每 20 分钟弹出 15 个 MS-DOS 窗口时,您会觉得自己没有将它们安装为 Windows 服务.

The other major annoyance with Windows Scheduler is that it runs interactively and not as a background process. When 15 MS-DOS windows pop up every 20 minutes during an RDP session, you'll kick yourself that didn't install them as Windows Services instead.

无论您选择什么,我当然都建议您将处理代码与控制台应用程序或 Windows 服务分离到不同的组件中.然后,您可以选择从控制台应用程序调用工作进程并将其挂接到 Windows 调度程序中,或者使用 Windows 服务.

Whatever you choose I certainly recommend you separate out your processing code into a different component from the console app or Windows Service. Then you have the choice, either to call the worker process from a console application and hook it into Windows Scheduler, or use a Windows Service.

您会发现安排 Windows 服务并不有趣.一个相当常见的情况是您有一个长时间运行的进程,您希望定期运行.但是,如果您正在处理一个队列,那么您真的不希望同一个 worker 的两个实例处理同一个队列.因此,您需要管理计时器,以确保您长时间运行的进程的运行时间超过指定的计时器间隔,直到现有进程完成后,它才会再次启动.

You'll find that scheduling a Windows Service isn't fun. A fairly common scenario is that you have a long running process that you want to run periodically. But, if you are processing a queue, then you really don't want two instances of the same worker processing the same queue. So you need to manage the timer, to make sure if your long running process has run longer than the assigned timer interval, it doesn't kick off again until the existing process has finished.

写完所有这些之后,您会想,为什么我不直接使用 Thread.Sleep?这允许我让当前线程继续运行,直到它完成,然后暂停间隔开始,线程进入睡眠状态并在所需时间后再次启动.整洁!

After you have written all of that, you think, why didn't I just use Thread.Sleep? That allows me to let the current thread keep running until it has finished and then the pause interval kicks in, thread goes to sleep and kicks off again after the required time. Neat!

然后你阅读互联网上的所有建议,很多专家告诉你这是非常糟糕的编程实践:

Then you then read all the advice on the internet with lots of experts telling you how it is really bad programming practice:

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

所以你会挠头想,WTF,撤消挂起的结账 -> 是的,我确定 -> 撤消今天的所有工作......该死的,该死的,该死的......

So you'll scratch your head and think to yourself, WTF, Undo Pending Checkouts -> Yes, I'm sure -> Undo all today's work..... damn, damn, damn....

然而,我确实喜欢这种模式,即使每个人都认为这是废话:

However, I do like this pattern, even if everyone thinks it is crap:

单线程方法的 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();
}

代码实例化了一个单独的线程并附加了我们的worker对它起作用.然后它启动线程并让 OnStart 事件完成,以便 Windows 不会认为该服务已挂起.

The code instantiates a separate thread and attaches our worker function to it. Then it starts the thread and lets the OnStart event complete, so that Windows doesn't think the service is hung.

用于单线程方法的 Worker 方法.

/// <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 (死链接)

多年来我一直在运行许多这样的 Windows 服务,它对我有用.我仍然没有看到人们同意的推荐模式.只做对你有用的事.

I've been running lots of Windows Services like this for years and it works for me. I still haven't seen a recommended pattern that people agree on. Just do what works for you.

这篇关于Windows 服务与计划任务的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆