IT박스

Windows 서비스 및 예약 된 작업

itboxs 2020. 8. 2. 17:53
반응형

Windows 서비스 및 예약 된 작업


프로그램을 반복적으로 실행하기위한 예약 된 작업과 Windows 서비스의 장단점은 무엇입니까 (예 : 2 분마다)?


최신 정보:

내 원래 답변 이후 거의 4 년이 지나고이 답변은 매우 오래된 것입니다. TopShelf 가 Windows 서비스를 개발 한 이래로 쉬워 졌습니다. 이제 장애 조치를 지원하는 방법을 알아야합니다.

원래 답변 :

저는 Windows 스케줄러의 팬이 아닙니다. 위의 @moodforall이 지적한 대로 사용자의 비밀번호를 제공해야 합니다. 누군가가 사용자의 비밀번호를 변경하면 재미 있습니다.

Windows 스케줄러의 또 다른 주요 문제점은 백그라운드 프로세스가 아니라 대화식으로 실행된다는 것입니다. RDP 세션 중에 20 분마다 15 개의 MS-DOS 창이 나타나면 대신 Windows 서비스로 설치하지 않은 창이 나타납니다.

무엇을 선택하든 분명히 처리 코드를 콘솔 앱 또는 Windows 서비스와 다른 구성 요소로 분리하는 것이 좋습니다. 그런 다음 콘솔 응용 프로그램에서 작업자 프로세스를 호출하여 Windows 스케줄러에 연결하거나 Windows 서비스를 사용할 수 있습니다.

Windows 서비스 예약이 즐겁지 않다는 것을 알게 될 것입니다. 상당히 일반적인 시나리오는 프로세스를 오래 실행하여 주기적으로 실행하려는 것입니다. 그러나 대기열을 처리하는 경우 동일한 작업자의 두 인스턴스가 동일한 대기열을 처리하는 것을 원하지 않습니다. 따라서 장기 실행 프로세스가 지정된 타이머 간격보다 오래 실행되었는지 확인하려면 타이머를 관리해야합니다. 기존 프로세스가 완료 될 때까지 다시 시작되지 않습니다.

그 모든 것을 작성한 후에 왜 Thread.Sleep을 사용하지 않았습니까? 그러면 스레드가 끝날 때까지 현재 스레드를 계속 실행 한 다음 일시 중지 간격이 시작되고 스레드가 절전 모드로 전환되고 필요한 시간이 지나면 다시 시작됩니다. 산뜻한!

그런 다음 많은 전문가와 함께 인터넷에서 모든 조언을 읽고 그것이 실제로 프로그래밍에 얼마나 나쁜지 알려줍니다.

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

그래서 당신은 당신의 머리를 긁을 것이며, WTF, Undo Pending Checkouts-> 그렇습니다, 확실합니다-> 오늘의 모든 작업을 취소하십시오 ..... 젠장, 젠장, 젠장 ....

그러나 모두가 쓰레기라고 생각 하더라도이 패턴을 좋아합니다.

단일 스레드 방식의 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));
}

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 AUTHORITY\SYSTEM 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 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 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, i.e. they won't even realize they exist and can be configured / stopped / rescheduled and so on.


In .NET development, I normally start off by developing a Console Application, which will run will all logging output to the console window. However, this is only a Console Application when it is run with the command argument /console. When it is run without this parameter, it acts as a Windows Service, which will stay running on my own custom coded scheduled timer.

Windows Services, I my mind, are normally used to manage other applications, rather than be a long running application. OR .. they are continuously-running heavyweight applications like SQL Server, BizTalk, RPC Connections, IIS (even though IIS technically offloads work to other processes).

Personally, I favour scheduled tasks over Window Services for repititive maintenance tasks and applications such as file copying/synchronisations, bulk email sending, deletion or archiving of files, data correction (when other workarounds are not available).

For one project I have been involved in the development of 8 or 9 Windows Services, but these sit around in memory, idle, eating 20MB or more memory per instance. Scheduled tasks will do their business, and release the memory immediately.


The word 'serv'ice shares something in common with 'serv'er. It is expected to always be running, and 'serv'e. A task is a task.

Role play. If I'm another operating system, application, or device and I call a service, I expect it to be running and I expect a response. If I (os, app, dev) just need to execute an isolated task, then I will execute a task, but if I expect to communicate, possibly two way communication, I want a service. This has to do with the most effective way for two things to communicate, or a single thing that wants to execute a single task.

Then there's the scheduling aspect. If you want something to run at a specific time, schedule. If you don't know when you're going to need it, or need it "on the fly", service.

My response is more philosophical in nature because this is very similar to how humans interact and work with another. The more we understand the art of communication, and "entities" understand their role, the easier this decision becomes.

All philosophy aside, when you are "rapidly prototyping", as my IT Dept often does, you do whatever you have to in order to make ends meet. Once the prototyping and proof of concept stuff is out of the way, usually in the early planning and discovering, you have to decide what's more reliable for long term sustainability.

OK, so in conclusion, it's highly dependent on a lot of factors, but hopefully this has provided insight instead of confusion.


A Windows service doesn't need to have anyone logged in, and Windows has facilities for stopping, starting, and logging the service results.

A scheduled task doesn't require you to learn how to write a Windows service.


  1. It's easier to set up and lock down windows services with the correct permissions.
  2. Services are more "visible" meaning that everyone (ie: techs) knows where to look.

Why not provide both?

In the past I've put the 'core' bits in a library and wrapped a call to Whatever.GoGoGo() in both a service as well as a console app.

With something you're firing off every two minutes the odds are decent it's not doing much (e.g. just a "ping" type function). The wrappers shouldn't have to contain much more than a single method call and some logging.


This is an old question but I will like to share what I have faced.

Recently I was given a requirement to capture the screenshot of a radar (from a Meteorological website) and save it in the server every 10 minutes.

This required me to use WebBrowser. I usually make windows services so I decided to make this one service too but it would keep crashing. This is what I saw in Event Viewer Faulting module path: C:\Windows\system32\MSHTML.dll

Since the task was urgent and I had very less time to research and experiment, I decided to use a simple console application and triggered it as a task and it executed smoothly.

I really liked the article by Jon Galloway recommended in accepted answer by Mark Ransom.

Recently passwords on the servers were changed without acknowledging me and all the services failed to execute since they could not logon. So ppl claiming in the article comments that this is a problem. I think windows services can face same problem (Pls. correct me if I am wrong, I am jus a newbie)

Also the thing mentioned, if using task scheduler windows pop up or the console window pops up. I have never faced that. It may pop up but it is at least very instantaneous.


Windows services want more patience until it's done. It has a bit hard debug and install. It's faceless. If you need a task which must be done in every second, minute or hour, you should choice Windows Service.

Scheduled Task is quickly developed and has a face. If you need a daily or weekly task, you can use Scheduled Task.


Generally, the core message is and should be that the code itself must be executable from each and every "trigger/client". So it should not be rocket science to switch from one to the other approach.

In the past we used more or less always Windows Services but since also more and more of our customers switch to Azure step by step and the swap from a Console App (deployed as a Scheduled Task) to a WebJob in Azure is much easier than from a Windows Service, we focus on Scheduled Tasks for now. If we run into limitations, we just ramp up the Windows Service project and call the same logic from there (as long as customers are working OnPrem..) :)

BR, y

참고URL : https://stackoverflow.com/questions/390307/windows-service-vs-scheduled-task

반응형