windows service vs scheduled task

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


Update:

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...

Original Answer:

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.

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.

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.

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.

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

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 method for the single-thread approach.

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();
}

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 method for the single-thread approach.

/// <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 method for the single-thread approach.

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));
}

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

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.


Some misinformation here. Windows Scheduler is perfectly capable of running tasks in the background without windows popping up and with no password required. Run it under the NT AUTHORITYSYSTEM account. Use this schtasks switch:

/ru SYSTEM

But yes, for accessing network resources, the best practice is a service account with a separate non-expiring password policy.

EDIT

Depending on your OS and the requirements of the task itself, you may be able to use accounts less privileged than Localsystem with the /ru option.

From the fine manual,

/RU username

A value that specifies the user context under which the task runs. 
For the system account, valid values are "", "NT AUTHORITYSYSTEM", or "SYSTEM". 
For Task Scheduler 2.0 tasks, "NT AUTHORITYLOCALSERVICE", and 
"NT AUTHORITYNETWORKSERVICE" are also valid values.

Task Scheduler 2.0 is available from Vista and Server 2008.

In XP and Server 2003, system is the only option.


What's the overhead of starting and quitting the app? Every two minutes is pretty often. A service would probably let the system run more smoothly than executing your application so frequently.

Both solutions can run the program when user isn't logged in, so no difference there. Writing a service is somewhat more involved than a regular desktop app, though - you may need a separate GUI client that will communicate with the service app via TCP/IP, named pipes, etc.

From a user's POV, I wonder which is easier to control. Both services and scheduled tasks are pretty much out of reach for most non-technical users, ie they won't even realize they exist and can be configured / stopped / rescheduled and so on.

链接地址: http://www.djcxy.com/p/38908.html

上一篇: 如何将Windows计划任务设置为在后台运行?

下一篇: Windows服务vs计划任务