4

Possible Duplicate:
Compare using Thread.Sleep and Timer for delayed execution

I am considering whether to use a System.Threading.Timer or Thread.Sleep in my ASP.NET Web Application. I looked for the differences of them. Period or the Sleep will be 100ms. AFAIK if I use a Timer it will not block running thread, but Sleep will block running thread.

Since the interval is very small, would it be better to choose Thread.Sleep(150) ?

Edit: I tend to use it like a timer on not thread pool thread. I know Timers will be run on thread pool, but I don't want to keep thread pool thread for such an operation

Community
  • 1
  • 1
Mehmet
  • 211
  • 1
  • 4
  • 12
  • This really depends on the situation! – Stefan Jan 17 '12 at 12:30
  • 2
    Depends on what you want to achieve. Use Sleep if you need the running thread to wait for something to get ready. Use Timer if you want to schedule a method to run at specified intervals. – MrKiane Jan 17 '12 at 12:30
  • why do you want to make the running thread sleep when you have another option? – Jahan Zinedine Jan 17 '12 at 12:30
  • Hello Mehmet. Please see this previous question & answer, specifically the answer provided by @EricRosenberger as I believe it answers your question. http://stackoverflow.com/questions/391621/compare-using-thread-sleep-and-timer-for-delayed-execution – Dr. Andrew Burnett-Thompson Jan 17 '12 at 12:31
  • I want my method to run forever (infinitely). And it has to check for some condition quite often (100ms interval). I am just thinking how I utilize the CPU usage. Maybe it would be better to create own thread rather than using thread pool thread and Sleep on that thread? – Mehmet Jan 17 '12 at 12:38

3 Answers3

5

I would recommend reading:

Comparing the Timer Classes in the .NET Framework Class Library

None of the timers will block the running thread, however the frequency at which they tick as a result of activity on the application's main thread differs as described in the above article.

Which you use really depends on the end result you desire! Although Thread.Sleep is viewed by most people as an anti-pattern.

ColinE
  • 68,894
  • 15
  • 164
  • 232
  • +1 for Thread.Sleep an anti-pattern. I tend to use it just in testing to simulate a "long wait". – Dr. Andrew Burnett-Thompson Jan 17 '12 at 12:34
  • I may understand why Thread.Sleep is an anti-pattern, but what if I tend to use it like a timer on not thread pool thread? I know Timers will be run on thread pool, but I don't want to keep thread pool thread for such an operation – Mehmet Jan 17 '12 at 12:41
  • 1
    @Mehmet say your Thread.Sleep pauses for 150 ms but the execution of code takes a variable amount of time between 1ms and 100ms then your timer interval varies from 151-251ms, i.e. it is not accurate. The Timer implementation you are gauranteed to receive an event as close to 150ms as possible, no matter how long the timer execute method takes. – Dr. Andrew Burnett-Thompson Jan 17 '12 at 15:39
  • 1
    @Dr.AndrewBurnett-Thompson - an accurate interval is not always required or desirable. A spec may well say, 'in order to reduce loading on the server, you must wait at least 2 seconds after receiving the server reply before polling the server again'. Also, using timer callbacks can be awkward when code is nested several levels deep. Insisting on using timers can turn a simple sleep() into a complex state-engine that has to submit itself to the timer as a state object and handle the timeout later. Inappropriate use of timers is as much an anti-patterns as misuse of sleep(). – Martin James Jan 17 '12 at 17:34
  • @MartinJames of course, the right tool for the job. Its unclear what the questioner really needs but if you read his previous question I refer to he seems to need to poll incoming messages in a chat application every 100ms and has issues with CPU spiking (possibly from thread creation), so its not just a one off wait. – Dr. Andrew Burnett-Thompson Jan 17 '12 at 19:13
3

Thread.Sleep() has some uses for which it is vital. These are few and far between, and if you're using any number higher than about 1 as the argument you almost certainly don't have one.

If it's even possible for a timer to be used instead, then you definitely don't have one. Don't block a perfectly good thread when the alternative isn't even difficult.

Do be careful of the case where a timer is triggered while the previous trigger is still running. Depending on the nature of the operation you will want to either:

  1. Ignore this, if the code called is safe for multiple simultaneous calls then this may be fine. Of course, you have to know that it's fine.
  2. Lock on the timer-triggered operation. Be aware that you can end up with a queue of lots of pending operations.
  3. Lock on the timer-triggered operation, try to obtain the lock with a timeout of zero and if you fail then skip it - there's a thread still here from the last time.
  4. Have the timer as a one-off timer that you restart at the end of each call.
Jon Hanna
  • 110,372
  • 10
  • 146
  • 251
  • Thanks. I used Monitor.TryEnter(LockerObject) at the beginning of the Callback function. I hope it will handle your 3rd case( try to obtain the lock with a timeout of zero...). But I didn't apply your 4th case, is it so vital to restart timer at the end of each call? – Mehmet Jan 17 '12 at 13:04
  • 1
    Thread.Sleep() has some uses for which it is very useful. These are more common in certain classes of app ,s eg. comms and process control. If you're using any number lower than about 2 as the argument you may well be misusing sleep() loops as an inter-thread comms mechanism - something that introduces resource-waste and latency. If a thread needs a 10-second delay, sleep(10000) is just about as simple as you can get. – Martin James Jan 17 '12 at 13:26
  • 1
    Mehmet. You only need to take one of the approaches given, though you want the form of `TryEnter` with an explicit timeout `if(!Monitor.TryEnter(LockerObject, 0))return;`. Be careful to call `Exit` in a `finally` unless perhaps you want the timer method to stop working in the face of potentially corrupt data. @MartinJames yes, another common case is low-level threading code used by higher-level code like this. – Jon Hanna Jan 17 '12 at 13:45
2

Please see this previous question & answer specifically the answer provided by @EricRosenberger as I believe it answers your question.

With regard to your situation, I believe you are asking in relation to this question you previously asked? Ie: You have an ASP.NET application which uses threads and the CPU usage is spiking, but it doesnt spike when using Systen.Threading.Timer. It may be off-topic for this current Q but to help your situation overall you may find that as Eric Rosenberger states the creation and destruction of threads might be what is causing your CPU spike not the actual implementation of code run inside the thread.

Best regards,

Community
  • 1
  • 1
Dr. Andrew Burnett-Thompson
  • 20,980
  • 8
  • 88
  • 178
  • It's a bit annoying when you can only give a good answer to a question by researching other questions by the same user! – ColinE Jan 17 '12 at 12:38
  • @ColinE sorry realise it a mess to cross pollenate threads, but I had previously answered Mehmet's other question hence was familiar with it. Not that I have that much spare time to go looking!! :p – Dr. Andrew Burnett-Thompson Jan 17 '12 at 12:40
  • Thanks, I already read that thread but it does not answer my specific question – Mehmet Jan 17 '12 at 12:43