4

I have a Windows Service that is meant to run a 2-minute job once a day. The remaining 23:58 of the day, it just sits around looking pretty.

My question relates firstly to the idle time: is it better to use a Timer.Tick, or a Thread.Sleep? Is there any difference between the resources either of these use?

Secondly, during that idle time, if someone shuts down the Windows Service, do I need to interrupt those idle threads for the program to shut down cleanly, or will the Shutdown handle it for me?

Thirdly, am I barking up the wrong tree by using a Windows Service? It would seem to make sense to put a record into the Windows Task Scheduler, but I couldn't find any way to do that using InstallShield, which is what we're using to deploy our product. Any better ideas?

Shaul Behr
  • 36,951
  • 69
  • 249
  • 387

6 Answers6

3

If you start a background thread with ThreadPool.QueueUserWorkItem I think you could have a Thread.Sleep in there and when you shut the service down you would not have to do anything with it. I think Timer Tick would automatically do the thread creation for you when it ticks, so you would have to do even less if you used that (out of the two the timer tick would, I think match what you want to achieve better so would be the better choice).

This definately feels like something that would be better done by a scheduler like you say though. I don't know if you can do it directly within InstallShield but perhaps you could create a little console app that you run from the installer that based on a command line argument either talks to the windows task schedular API - http://msdn.microsoft.com/enus/library/windows/desktop/aa383614(v=vs.85).aspx to register itself or does the job you want to acheive (i.e -install - set it up on the schedular, no args do whatever it is you need to do once a day).

I think it is a C++ API so you could do a bit of p/invoke or, better, just have some managed C++ in a class libaray and reference it from a c# based console application.

kmp
  • 10,535
  • 11
  • 75
  • 125
3

FWIW, InstallShield doesn't have native capabilities to define scheduled tasks but it does support VBScript, C++ and InstallScript custom actions. All of these options support calling COM Automation Interfaces and Microsoft exposes the task scheduler through a series of Task Scheduler objects.

Task Scheduler Reference

CPU activity aside, a Windows service running all the time also consumes memory. In fact, every version of Windows has less services.

Why Windows 8 Uses So Much Less Memory Than Windows 7

Christopher Painter
  • 54,556
  • 6
  • 63
  • 100
2

I would use Timer.Tick. Thread.Sleep blocks the thread and you can not abort the thread nicely when you shut down your service.

Albin Sunnanbo
  • 46,430
  • 8
  • 69
  • 108
2

I would recommend the Windows Service as you are just duplicating its functionality otherwise.

If InstallShield doesn't support adding to the task scheduler, then can you get InstallShield to run a batch script or a small .net app after install to add it to the task scheduler?

Adam
  • 16,089
  • 6
  • 66
  • 109
2

As long as your requirements for scheduling are very simple (as they currently are), I think the service approach is fine.

Personally, I don't really like the windows scheduler because I find it unstable and annoying to maintain (admittedly, I haven't tried the new version in Windows 2008).

I would probably go with a scheduling library like Quartz.Net if I were to build an application with more advanced scheduling requirements.

Jonas Høgh
  • 10,358
  • 1
  • 26
  • 46
1

If you dont have scheduling app like autosys, windows service should be better option, also I dnt see any harm in thread.sleep, it is meant to pause app and utilize 0% cpu

Brijesh Mishra
  • 2,738
  • 1
  • 21
  • 36
  • What about the answer by @AlbinSunnabo, which notes that `Thread.Sleep` blocks the thread so you can't abort cleanly? – Shaul Behr Dec 22 '11 at 08:05