To use or not to use worker thread in Windows Service?
-
IMO both could work well, you should choose what suits you most. I would go for threads if the job may take long, has lots of state, or is rather complex; and for a timer when it is rather simple, short, lightweight. :)
Luc Pattyn [Forum Guidelines] [Why QA sucks] [My Articles] Nil Volentibus Arduum
Please use <PRE> tags for code snippets, they preserve indentation, and improve readability.
Luc, thanks for your answer. What do you mean by "has lots of state"?
-
Luc, thanks for your answer. What do you mean by "has lots of state"?
Sorry, should have been lots of states or state variables, and is actually only relevant if you have to restore the object from one timer tick to the next, it probably does not apply to what you are trying. It is most relevant when a job is going to be sliced in smaller jobs that may be handled by a number of consecutive timer ticks. :)
Luc Pattyn [Forum Guidelines] [Why QA sucks] [My Articles] Nil Volentibus Arduum
Please use <PRE> tags for code snippets, they preserve indentation, and improve readability.
-
I am a newbie to C# development (have been doing C++ for years) and Windows Service implementation. While reading on the subject I found that there are 2 different approaches 1) Use timer event without additional worker thread - illustrated here: http://blogs.msdn.com/b/bclteam/archive/2005/03/15/396428.aspx[^] 2) Use worker thread - illustrated here: http://msdn.microsoft.com/en-us/library/system.serviceprocess.servicebase%28VS.80%29.aspx[^] I seem to find the first approach simpler and easier to use. Can anyone explain if there are any drawbacks for this approach? Is there any reason to prefer worker thread approach?
I generally use a System.Timers.Timer -- they work for me. An additional benefit (to me anyway) is that the handler method enters and exits on each cycle rather than running indefinitely. In my opinion, the method shouldn't need to know that it is implementing a periodic function. Using a Timer allows me to separate responsibilities. The downside is that if the code takes longer to execute than the timer's interval, you wind up with two executions running at the same time -- you would need to allow for that or prevent it.
-
I generally use a System.Timers.Timer -- they work for me. An additional benefit (to me anyway) is that the handler method enters and exits on each cycle rather than running indefinitely. In my opinion, the method shouldn't need to know that it is implementing a periodic function. Using a Timer allows me to separate responsibilities. The downside is that if the code takes longer to execute than the timer's interval, you wind up with two executions running at the same time -- you would need to allow for that or prevent it.
Would this be a correct approach to prevent more than one execution:
protected override void OnStart(string\[\] args) { WriteEventEntry("TestService starting...", EventLogEntryType.Information, 100, 100); timer.Elapsed += new ElapsedEventHandler(timer\_Tick); timer.Interval = 5000; timer.Enabled = true; } private void timer\_Tick(object sender, EventArgs e) { timer.Enabled = false; // stop timer to prevent more than one execution WriteEventEntry(DateTime.Now.ToString() + " timer ticked...", EventLogEntryType.Information, 100, 100); // do something useful here timer.Enabled = true; // start timer again }
?
-
Would this be a correct approach to prevent more than one execution:
protected override void OnStart(string\[\] args) { WriteEventEntry("TestService starting...", EventLogEntryType.Information, 100, 100); timer.Elapsed += new ElapsedEventHandler(timer\_Tick); timer.Interval = 5000; timer.Enabled = true; } private void timer\_Tick(object sender, EventArgs e) { timer.Enabled = false; // stop timer to prevent more than one execution WriteEventEntry(DateTime.Now.ToString() + " timer ticked...", EventLogEntryType.Information, 100, 100); // do something useful here timer.Enabled = true; // start timer again }
?
Yes, but I suggest you use a try/catch/finally with the
timer.Enabled = true;
in the finally. (Unless you want your Service to stop when it encounters an Exception.) -
I am a newbie to C# development (have been doing C++ for years) and Windows Service implementation. While reading on the subject I found that there are 2 different approaches 1) Use timer event without additional worker thread - illustrated here: http://blogs.msdn.com/b/bclteam/archive/2005/03/15/396428.aspx[^] 2) Use worker thread - illustrated here: http://msdn.microsoft.com/en-us/library/system.serviceprocess.servicebase%28VS.80%29.aspx[^] I seem to find the first approach simpler and easier to use. Can anyone explain if there are any drawbacks for this approach? Is there any reason to prefer worker thread approach?
I mostly use threads, and if you want to keep the periodicity logic apart from the rest of the logic you can use something similar to this: while(true) { DoStuff(); sleep(1000); } The good thing about this, is that you running this code through a separate thread; thus it does not interfere with the UI thread. On large processes this will save you a lot of problems with the application not responding or working slower than expected. Anyway as someone else told you both solutions could work, I'd use timer for trivial tasks and the thread worker for more complex stuff, but that's just my choice.
-
I am a newbie to C# development (have been doing C++ for years) and Windows Service implementation. While reading on the subject I found that there are 2 different approaches 1) Use timer event without additional worker thread - illustrated here: http://blogs.msdn.com/b/bclteam/archive/2005/03/15/396428.aspx[^] 2) Use worker thread - illustrated here: http://msdn.microsoft.com/en-us/library/system.serviceprocess.servicebase%28VS.80%29.aspx[^] I seem to find the first approach simpler and easier to use. Can anyone explain if there are any drawbacks for this approach? Is there any reason to prefer worker thread approach?
I use a timer, it just seems neater.
-
I am a newbie to C# development (have been doing C++ for years) and Windows Service implementation. While reading on the subject I found that there are 2 different approaches 1) Use timer event without additional worker thread - illustrated here: http://blogs.msdn.com/b/bclteam/archive/2005/03/15/396428.aspx[^] 2) Use worker thread - illustrated here: http://msdn.microsoft.com/en-us/library/system.serviceprocess.servicebase%28VS.80%29.aspx[^] I seem to find the first approach simpler and easier to use. Can anyone explain if there are any drawbacks for this approach? Is there any reason to prefer worker thread approach?
JoeSchmoe007 wrote:
Is there any reason to prefer worker thread approach?
It depends on what you are trying to do.
Timer
is used when you want to get the callback in periodic intervals. One thing to note is, timer will fire the callback even if the previous call is in progress. All it does is queuing the job to a thread pool thread. If you don't have something to execute periodically, spawn a thread or use one from thread pool. I have seen people simulating the timer's behavior by spawning worker threads and sleeping on it, which is of course a bad design. There is no difference internally because both are using separate thread to do the job. :)Best wishes, Navaneeth
-
JoeSchmoe007 wrote:
Is there any reason to prefer worker thread approach?
It depends on what you are trying to do.
Timer
is used when you want to get the callback in periodic intervals. One thing to note is, timer will fire the callback even if the previous call is in progress. All it does is queuing the job to a thread pool thread. If you don't have something to execute periodically, spawn a thread or use one from thread pool. I have seen people simulating the timer's behavior by spawning worker threads and sleeping on it, which is of course a bad design. There is no difference internally because both are using separate thread to do the job. :)Best wishes, Navaneeth
Can you elaborate why sleeping on the worker thread is bad design? I see this approach used often. What design would you recommend instead when worker thread is used?
-
Can you elaborate why sleeping on the worker thread is bad design? I see this approach used often. What design would you recommend instead when worker thread is used?
JoeSchmoe007 wrote:
Can you elaborate why sleeping on the worker thread is bad design?
Because
Thread.Sleep
may or may not sleep for more time than you specified. Take a look at this[^] article. IMO, the decision to use sleep is also subjective. If you need accuracy on the intervals, you should not useThread.Sleep
. If you are waitting for some condition to happen, say wait for an external device to be up, you should useWaitHandle
instead ofThread.Sleep
. Consider the following example: A windows service which is expected to do some job at every 10 minutes accurately (Eg: downloading a webpage and indexing the contents). You start the service and 12.00 and it should run at 12.10, 12.20 and so on. Unfortunatly the work took 15 minutes to complete. Now the program won't run at 12.20 instead it will run at 12.35. You loose the accuracy! This is where timers are useful.JoeSchmoe007 wrote:
What design would you recommend instead
A windows service is something which is active all the time. If your application is doing the work only at specific intervals then it is not a good candidate for a service. It'd be better to create it as a normal console application and schedule it using the operating system's scheduler. :)
Best wishes, Navaneeth
-
I mostly use threads, and if you want to keep the periodicity logic apart from the rest of the logic you can use something similar to this: while(true) { DoStuff(); sleep(1000); } The good thing about this, is that you running this code through a separate thread; thus it does not interfere with the UI thread. On large processes this will save you a lot of problems with the application not responding or working slower than expected. Anyway as someone else told you both solutions could work, I'd use timer for trivial tasks and the thread worker for more complex stuff, but that's just my choice.
Hmm ... windows services don't have a UI thread :-O
-
Hmm ... windows services don't have a UI thread :-O
Touche!! And that's why my mamma told me I need to read the question before giving an answer :$