Thread.Sleep is a sign of a poorly designed program.

Thread.Sleep has it's use: simulating lengthy operations while testing/debugging on an MTA thread.  In .NET there's no other reason to use it.

Thread.Sleep(n) means block the current thread for at least the number of timeslices (or thread quantums) that can occur within n milliseconds.  The length of a timeslice is different on different versions/types of Windows and different processors and generally ranges from 15 to 30 milliseconds.  This means the thread is almost guaranteed to block for more than n milliseconds.  The likelihood that your thread will re-awaken exactly after n milliseconds is about as impossible as impossible can be.  So, Thread.Sleep is pointless for timing.

Threads are a limited resource, they take approximately 200,000 cycles to create and about 100,000 cycles to destroy.  By default they reserve 1 megabyte of virtual memory for its stack and use 2,000-8,000 cycles for each context switch.  This makes any waiting thread a *huge* waste.

If the current thread is a foreground thread, Thread.Sleep(n) also means your application cannot exit for >n milliseconds.  After all foreground threads have completed, the CLR will allow an application to terminate.  If the current thread is a background thread, and the application exits the thread will simply never be awoken (not good if you need your objects to be disposed or finalized).

STA threads have an implicit requirement to not make blocking calls.  STA threads use a message queue (of finite size) to communicate with the outside world; that communication occurs whether you explicitly use it or not.  When you block your STA thread with Thread.Sleep you're blocking that communication and run the risk of the queue overflowing.  A WinForm thread must be STA, so it has the same implicit requirement to not make blocking calls simply to support being an apartment.  A GUI should never make calls that can affect the responsiveness of the user interface, for obvious reasons.

There is one non-breaking use for Thread.Sleep: Thread.Sleep(0).  This tells the system you want to forfeit the rest of the thread's timeslice and let another, waiting, thread run.  If there are no other threads waiting to run you still relinquish your timeslice.  If There are other threads waiting to run, you won't be sure when you get control back; if the waiting thread has a higher priority, you may never get control back.  Thread.Sleep(0) effectively tells the OS that you're better at scheduling processes than it is and you'll likely affect the way it can schedule threads and processes and affect the responsiveness of the entire system if you're using Sleep(0) a lot.

As future versions of the CLR and CLR hosts are implemented they will eventually implement threading without a direct dependence on unmanaged threads (e.g. managed entirely by the CLR using fibers.)  Which means Thread.Sleep will have to be reimplemented to do something different (e.g. if Sleep(0) means relinquish the current thread's timeslice to the OS and there is no current OS thread then Sleep(0) means nothing.  If Thread.Sleep is not re-implemented Thread.Thread(0) means block all fibers, or managed threads, associated with the current OS thread.  You never want to cause other threads to suspend, especially arbitrarily).  So, System.Thread is not future-friendly.

Thread.Sleep has been used for many things it shouldn't be used for.  Here's a list of the common mistakes:

The thread needs to wait for another thread to complete
In this case no value, other than infinite, passed to Thread.Sleep will be correct.  You simply don't know when the other thread will complete using this method.  If the thread completed after Sleep returned you'll likely have synchronization problems.  If the other thread completed before Sleep returned the thread was needlessly blocked for an amount of time rendering the benefits of multithreading limited or moot.  In the control circumstances where you've tested this it may seem like it always works; it just takes a busy program to cause it to faile: a defrag program, a sudden influx of network traffic, a network hiccup, etc.

The thread needs perform logic every n milliseconds
As noted earlier, Sleep means relinquish control.  When your thread gets control again isn't up to the thread; so it can't be used for periodic logic.

We don't know why Thread.Sleep is required; but if we take it out the application stops working
This is flawed logic because the application still doesn't work with Thread.Sleep.  This is really just spackling over the problem on that particular computer.  The original problem is likely a timing/synchronization issue, ignoring it by hiding it with Thread.Sleep is only going to delay the problem and make it occur in random, hard to reproduce ways.

Published Thursday, April 26, 2007 9:41 PM by PeterRitchie

Comments

# re: Thread.Sleep is a sign of a poorly designed program.

More generally creating explicity threads is a sign of flawed design. You should always use threadpool thread, except in some very scarse situations (such as when you need to adjust thread priority or if you need some foreground threads). Here is a NDepend CQL constraint that can help pinpoints these flaws: WARN IF Count > 0 IN SELECT METHODS WHERE IsDirectlyUsing "System.Threading.Thread.Sleep(Int32)" OR DepthOfIsCreating "System.Threading.Thread" == 0 Another good practice for multithreaded app is to use immutable types. Check out here: http://s3.amazonaws.com/NDependOnlineDemos/NDependMultiThreadedApp_viewlet_swf.html Patrick

Thursday, May 03, 2007 3:00 AM by Patrick Smacchia

# re: Thread.Sleep is a sign of a poorly designed program.

I use Thread.Sleep(x) to wait for hardware connected to PC to finish after I send it a comman. This is run in a BackgroundWorker Do Work routine as the last instruction. Given that I am waiting on something that is guaranteed to finish in x ms by hardware I can't see the problem with using Thread.Sleep.

Thursday, May 03, 2007 10:58 AM by Ryan Mohammed

# re: Thread.Sleep is a sign of a poorly designed program.

RE: Explicitly created threads:

It may be likely that it's rare that explicitly created threads are being used correctly or optimally; but, there are many valid uses to explicitly created threads.  That's not the case with Thread.Sleep.

Thursday, May 03, 2007 11:18 AM by PeterRitchie

# re: Thread.Sleep is a sign of a poorly designed program.

RE: Thread.Sleep waiting for hardware.  I'd have to see what hardware you're talking about; but I've never seen any hardware driver guarantee completion of anything within x ms.  So, that sounds suspect.

Even if your driver does provide that guarantee, there's no guarantee Thread.Sleep will awake after x ms; it's likely much longer than x and it depends on the CPU/OS and load.  Which means you're guaranteed to have a period of time where your thread is waiting needlessly (i.e. you've overshoot the "real" time, if the driver completed after 5 ms but the system granularity is 10 ms your thread won't awaken until >5ms after the hardware completed.)

When communicating with hardware I recommend using Asynchronous IO in .NET or completion ports in native.  That way your application is notified the moment the IO is completed, plus you don't have to needlessly create a second thread simply for waiting (which is extremely un-scalable).

Thursday, May 03, 2007 11:26 AM by PeterRitchie

# re: Thread.Sleep is a sign of a poorly designed program.

You missed a point about Thread.Sleep(0). On a uniprocessor system this has no effect and you need to P/Invoke SwitchToThread. Otherwise, I agree - Thread.Sleep is bad. Not in the same league as Thread.Abort, but still bad.

Friday, May 11, 2007 7:18 PM by Greg Beec

# re: Thread.Sleep is a sign of a poorly designed program.

Thanks for this article!

"The thread needs perform logic every n milliseconds" - under this header, you discouraged using the Sleep method also.  What would be an alternative?  Please note that, a Timer object can't be used under the circumstances.

Will greatly appreciate your insight into this!

Best Regards!

Raihan

Thursday, May 17, 2007 10:05 AM by Raihan U. Ahmed

# re: Thread.Sleep is a sign of a poorly designed program.

no doubt, it is :-), and I know very well, where in my programs are this beasts isolated :-)), preparing to kill them all ASAP :-), as I learn to use async delegates, thread pool, Begin/End calls, be sure :-)

I am smiling looking at most Delphi programs which are compiled into native code, but mostly behave quite unresponsive too ... they are written often by people who hate .NET for its slowness, LOL

Monday, July 09, 2007 6:04 AM by Petr Antos

# re: Thread.Sleep is a sign of a poorly designed program.

Tuesday, August 14, 2007 1:48 PM by Sean

# re: Thread.Sleep is a sign of a poorly designed program.

I'm using Thread.Sleep quite effectively for displaying progress for a file download in a console app. I realise a console app is a simplest case scenario (and no need fro MTA), but if there's a better way, I'd be interested to know what it is.

Wednesday, August 15, 2007 9:40 AM by Sean

# re: Thread.Sleep is a sign of a poorly designed program.

I'm using Thread.Sleep quite effectively for displaying progress for a file download in a console app. I realise a console app is a simplest case scenario (and no need for MTA), but if there's a better way, I'd be interested to know what it is.

Wednesday, August 15, 2007 9:40 AM by Sean

# re: Thread.Sleep is a sign of a poorly designed program.

Sean, I'd have to see some of the details of how you're downloading to offer an alternative.

Tuesday, August 21, 2007 6:49 PM by PeterRitchie

# re: Thread.Sleep is a sign of a poorly designed program.

I use thread.sleep() while flashing an embbedded controller. I use the serialPort class data recieved event. There are a few times where I have to slow things down for the controller, the PC is too fast. Do not know any other way to do this.

Wednesday, August 22, 2007 3:43 PM by Jeff

# re: Thread.Sleep is a sign of a poorly designed program.

Generally you are right - at least when it comes to the UI thread, but there are a few exceptions where Sleep is the only resonable solution because of flawed event design.

See the MSDN.VB.NET thread: "Why To Not Use Threading.Sleep in Your Application":

forums.microsoft.com/.../ShowPost.aspx ,where there is a very long discussion about this subject.

I don't see Sleep as a future problem. Of course the ones, who implement future versions, must ensure that Sleep still works the way it is expected to do and not blocks other threads.

Thursday, August 23, 2007 9:35 AM by CarstenK

# re: Thread.Sleep is a sign of a poorly designed program.

@CarstenK: "flawed event design" is another sign of a poorly design program.  If it weren't poorly designed, the programmer wouldn't think Thread.Sleep was needed.

Even with a poorly designed program, there's more alert-able (i.e. better) ways of blocking a thread.  WaitHandle.WaitOne, for example, offers a timeout overload.  Adding a timeout blocks your thread for at least that timeout or until the WaitHandle becomes unlocked.  You then have the option of unlocking whatever WaitHandle-derived object you're using to interrupt it and stop blocking earlier.

Maybe another blog post explaining that in detail is in order.

Thursday, August 23, 2007 10:04 AM by PeterRitchie

# re: Thread.Sleep is a sign of a poorly designed program.

Yes, flawed event design is poor design, but sometimes it is out of your control to do something about it like the examples with .NET SerialPort and bad hardware drivers in the MSDN.VB.NET thread.

There are many flaws in SerialPort (and Windows), but at least the problem with reopening a port is easy to handle by means of Sleep. Maybe not a pretty solution, but effective and you can live with that. It is much worse that SerialPort/Windows API/Drivers puts an 8-bit wide buffer on top of the 11-bit UART FIFO and in this way efficiently destroys any possibility for a precise break, 9th bit and error detection. I have just bought a $300 expensive kernel mode driver to handle that issue! Of course this is off topic, but I think that it puts things in perspective! There are much worse things than a harmless power nap now and then :-)

Thursday, August 23, 2007 3:45 PM by CarstenK

# re: Thread.Sleep is a sign of a poorly designed program.

System.Timers.Timer is a much better choice with the SerialPort example because you can abandon a timer without worry.

Thursday, August 23, 2007 6:14 PM by PeterRitchie

# re: Thread.Sleep is a sign of a poorly designed program.

No it is not as I have described in the MSDN.VB.NET thread! If you don't block the UI thread, the time you need to ensure that the background thread in SerialPort gets scheduled and can close down is of course MUCH longer because the UI thread has higher priority than background threads. Besides, nobody can estimate the necessary time when you don't block the UI thread. Is it 2 sec., 5 sec. or maybe 10 sec.?

It is a nice principle never ever to sleep the UI thread, but sometimes the alternative is much worse! If you call Application.DoEvents() before the Sleep(200) command, the display gets updated and before the user can press the mouse button again, the UI thread is ready, so (s)he don't notice anything. The alternative is to block all transmissions maybe 2 sec. after the port switch and that may irritate the user and will create an unreliable program. Maybe the time should have been 5 sec.?

Friday, August 24, 2007 12:51 AM by CarstenK

# re: Thread.Sleep is a sign of a poorly designed program.

Your UI thread should be taking very little CPU, regardless of it's priority difference to the background thread.  Most of the time it sits there doing nothing (well, waiting for messages...)

DoEvents is a bad design choice too, the messages it pumps can get out of order and it provides a perfect means of deadlocking, especially with a SerialPort object.

One problem is the time you give you sleep is arbitrary, most of the time the pause you get from Sleep isn't the same plus what you're asking for is just a guess too.

You can design yourself into a corner with pretty much anything; but with regard to timer, I'd be doing serial communications on a background thread and a timer (Forms timer if I'm expecting the UI thread to deal with anything, System.Timers otherwise) first an event to start some logic.  You can do what you want with a timer, as with anything else, the rest of your application's architecture has to support it.

Using Thread.Sleep is coupled to the fact that the thread using it be an MTA thread and that it not be a foreground thread for it to work.  That in itself is not a very cohesive design.

Friday, August 24, 2007 8:48 AM by PeterRitchie

# re: Thread.Sleep is a sign of a poorly designed program.

... and when the UI thread receives a message it gets busy or even very busy in case of big graphical jobs etc. In that case, you cannot guarantee how long time is needed to be sure that all background threads gets a chance of running. A simple question to you: "How much time is needed under worst case conditions if you don't block the UI thread?" If you cannot answer that question, your timer solution will not lead to a reliable design!

Of course the necessary time if you block the UI thread is also completely undefined, but if we test the system, find a time, which does not cause failure under heavy load conditions, and then add a resonable safety factor - say 10, we are still within resonable times - for example 50 mS x 10 = 500 mS. If the necessary time with the UI thread running is 500 mS and we use the same safety factor, we get 5 sec., which is so long that it may be noticed. That's the problem! SerialPort needs some time to close down. That's a fact. So either you Sleep the UI thread for e.g. 500 mS to be resonable sure or you use e.g. a 5 sec. timer. There are simply no other alternatives!

"DoEvents is a bad design choice too, the messages it pumps can get out of order and it provides a perfect means of deadlocking, especially with a SerialPort object."

That's one of those statements, which really need a better, technical explanation! DoEvents just empty the message queue. How can messages get out of order (except of course for WM_QUIT, WM_PAINT and WM_TIMER, which are always delayed until there are no more messages), how can it lead to deadlock situations and what makes the serial port so special in this case? For your information, I have used similar queue based, event driven, systems for highly demanding electronic process control since 1978, so you better come up with a very logical explanation. I don't buy everything ;-)

Saturday, August 25, 2007 3:29 AM by CarstenK

# re: Thread.Sleep is a sign of a poorly designed program.

"... and when the UI thread receives a message it gets busy or even very busy in case of big graphical jobs etc. In that case, you cannot guarantee how long time is needed to be sure that all background threads gets a chance of running. A simple question to you: "How much time is needed under worst case conditions if you don't block the UI thread?" If you cannot answer that question, your timer solution will not lead to a reliable design!"  What does that have to do with not using the SerialPort for x number of seconds.

If you don't need to use the serial port for x number of seconds, it's easy: start a timer and don't use the serial port until the timer elapses.  Simple as that.

All the available information about DoEvents is available on the Internet, a comment isn't an appropriate place to explain that in detail.

Saturday, August 25, 2007 7:20 AM by PeterRitchie

# re: Thread.Sleep is a sign of a poorly designed program.

I have to agree with Peter 100% on this one. (And I have also been developing extreme realtime industrial/space/milatary systems since the late 1970's). There simply is NO place for a "Sleep".

Phrasing the situation differently, why would you want a timed blocking mechanism which can not (optionally) be terminated early?

Can you guarentee that in 1,2,3,5 years the program will not evolve so that there is a need to "wake" a blocked thread early?

Do using WaitOne with a timeout provides equivilant functionallity (i.e. You can guarentee that the thread is blocked for a minimum time) provided you do not code something to explicitly wake it.

"and when the UI thread receives a message it gets busy or even very busy in case of big graphical jobs etc."

Right here I see a major design flaw!

I do heave graphical applications (e.g. realtime 3D display of ion beam etching gas dispersions) that are combined with realtime industrial control. The UI thread has a "monitor" which is implemented as a timer. The timer is configured to fire every 33mS (30fps), if 66mS (15fps) is exceeded between events an error message is logged.

This rate is accomplished by performing all graphical calculations in a background thread so that the UI thread simply has to do the rendering (which is actually done by the processor on the graphics card).

Under certain conditions the calculations them selves (for certain parts of the image) may take significantly longer, but this does NOT effect the UI thread.

I have been using this architecture since the early 1990's (originally in C, then C++, now C#) and it has proven quite reliable.

Friday, September 14, 2007 7:41 AM by TheCPUWizard

# re: Thread.Sleep is a sign of a poorly designed program.

This may have been covered already, but what about threaded methods that read/write to the file system? Here at Pixsy, all of our caught exceptions are forked off into a new thread and recorded to and XML file. However, if two exceptions are thrown at the same time, it is impossible without Sleep()ing to perform this write. The best solution is probably to set up a Windows Service and transfer the exception using Remoting to that service. When the service detects a concurrent file operation to the XML log, it can then reattempt to log the exception until it is logged. This poses a problem, although. In order to reattempt when the XML file is free, trying to write to the file must and catching an exception must be used as logic flow--which should never be done. Have any thoughts?

Friday, December 07, 2007 3:32 PM by Chris O.

# re: Thread.Sleep is a sign of a poorly designed program.

I'd have to see the code; but Windows doesn't limit writing to the file system in the same process like it does across processes.  Windows won't let multiple applications physically write to a file at the same time, it synchronizes that access.  This is because more than one process uses more than one thread; and it doesn't make sense to write to a file from more than one thread at a time.  Since Windows 3.x functions have not limited a single process writing to a file.  This is because 3.x was preemptive.  Two threads couldn't physically be running at the same time, so there was never a problem.  This backward compatibility was kept so old programs wouldn't break...

Again, I'd have to see the code, but essentially what's probably happening is you've added calls to Thread.Sleep() with increasing timeout values until your program worked.  This should be the first sign something's wrong.  You've tested it with a particular scenario and haven't taken into account slower devices (try doing the same thing to a network share over a busy 10Mb network connection to an overloaded server, or to a floppy drive).  Essentially what is happening is probably you've simply made writing to the file synchronous; making one thread sleep for a long enough period of time until the other thread has completed it's task (and usually longer...).  This is a waste of threads.

Friday, December 07, 2007 9:37 PM by PeterRitchie

# re: Thread.Sleep is a sign of a poorly designed program.

I am currently using Thread.Sleep to get past 'delayed write errors' when backing up a large amount of data to an external storage device in XP. It is a klooge, but I cannot figure out how to make the OS copy files without caching and eventually failing (I turned of caching in both source and destination drives and tried a lot of fixes suggested on forums, to no avail).

Saturday, January 12, 2008 7:47 AM by Jose Paul

# CSharp

Event handling subscribe / unsubscribe to an event

Saturday, April 05, 2008 3:07 PM by Confluence: Issues

# CSharp

Event handling subscribe / unsubscribe to an event

Saturday, April 05, 2008 3:31 PM by Confluence: Issues

# CSharp

Event handling subscribe / unsubscribe to an event

Saturday, April 05, 2008 3:52 PM by Confluence: Issues

# CSharp

Event handling subscribe / unsubscribe to an event

Saturday, April 05, 2008 3:52 PM by Confluence: Issues

# re: Thread.Sleep is a sign of a poorly designed program.

Thread.Sleep(0) is useful for playing nice with other application. If a thread is cpu-bounded on a single processor, say doing something in a tight for-loop, Thread.Sleep(0) will allow other applications, like Internet Explorer, to be more responsive and not as sluggish when not using Thread.Sleep(0).  

Wednesday, April 23, 2008 3:55 PM by Ray

# re: Thread.Sleep is a sign of a poorly designed program.

Prefer Thread.Sleep(1) to Thread.Sleep(0)

Wednesday, April 23, 2008 4:02 PM by PeterRitchie

# re: Thread.Sleep is a sign of a poorly designed program.

Tried it. Using Thread.Sleep(1) drops the CPU usage down to 3%, Thread.Sleep(0) offers near 100% usage while still allowing IE to be snappy. Without the Thread.Sleep call at all IE is sluggish.

Wednesday, April 23, 2008 4:17 PM by Ray

# re: Thread.Sleep is a sign of a poorly designed program.

WIndows Service, timeing is not crtical.

needs to be running and do something "about every xxx time periods"

so it needs to "sleep" most of the time.

what would you recomend ??

While( Not Exit Status){

DoWOrk();

SleepABout(20 seconds);

}

??

Friday, May 02, 2008 6:27 PM by denny

# re: Thread.Sleep is a sign of a poorly designed program.

Hi,

I am using thread.sleep in a mail sending function. After sending one mail this has to be stopped for at least 2 seconds (Server does not allow multiple mail sending at a session). And my program is successfull using this technique. Is there any alternative?

Tuesday, May 13, 2008 11:15 PM by Shaoun

# re: Thread.Sleep is a sign of a poorly designed program.

I think you're wrong.  Not to say there aren't plenty of example out there of bad use of Sleep, but this also doesn't mean there aren't plenty of good uses for it.

One example is trying to copy a file across the network as part of a large multi-file copy.  We all know that networks get temporary glitches and can fail file copies but they then suceeed moments later.  A retry with a delay between each is a perfect use for Sleep -- if you think there's a far superior alternative I'd love to hear it.

Use also mentioned in a comment above that you prefer Sleep(1) to Sleep(0) for being nice to other processes while running a CPU intensive app.  Sleep(1) instead of Sleep(0) here does EXACTLY what you've been saying was a misuse of Sleep in the main post -- you are guaranteeing that you'll give up at least 1ms (3 million processor cycles!!!) when nothing else may even want the CPU.  Sleep(0) here means "hey, if anyone is starved for CPU time, here take a quick slice, but if not I'd be happy to keep crunching away".

Saturday, May 17, 2008 5:43 PM by I like Sleep

# re: Thread.Sleep is a sign of a poorly designed program.

@I Like Sleep: As with any advice, you have to understand and accept it.  I wouldn't expect anyone to simply do anything I say without thinking about it and understanding it.  If you find that after what I said and your experiences and research you don't agree, that's great.  

But, I don't agree what you've said is good design.  With regard to waiting for retry, where do you do this sleep?  If you do it on the UI thread, you're making your UI non-responsive: very bad.  If you're starting up a new thread, how are you communicating back to the UI thread to retry?  If it's not the UI thread, what is it.  If it's a retry, how are you informing the user and providing the ability to abort the upcoming retry?  In the case of aborting the retry or exiting the application with a sleep in the background thread, you can't--you'd have to abandon the thread and start another if you wanted to offer the ability to perform the retry-able operation to the user, wasting 300,000 cycles to create a new thread and it eventually terminating.  Not giving up 300,000 cycles like what Sleep(x) does, but wasting them.  If you used a thread-pool thread for this and the thread pool had no more active threads your thread wouldn't run for 1 second--which usually results in "random" defect reports from your uses.  You can't abort the sleep without either resulting to bad practices or really obscure techniques.  With a delay between retries, you have to a) inform the user that you're going to retry, b) provide the ability to abort the upcoming retry, and c) not stop the application from exiting (i.e. if you have a non-background thread running int the background stuck on Sleep, the application won't exit from memory until the Sleep returns or some pre-defined amount of time when the CLR gives up on the thread.  To support these cases I would recommend a timer.  When the timer elapses initiate a retry.  If the user wants to abort, you simply reset the timer; if they want to exit the app, it's the same thing.

Thread.Sleep() is implemented by calling the native SleepEx.  Read the documentation for SleepEx (I've added it to the .NET 2.0 Thread.Sleep documentation as community content) SleepEx(0) relinquishes control to other threads "of equal priority that is ready to run".  This means you're *not* relinquishing control to anyone starved for CPU (i.e. you're not relinquishing control to a lower- or higher-priority thread) which can lead to starvation and race conditions.  Plus, use of Sleep(0) can actually use up more CPU cycles that Sleep(1) because the OS has to eventually get involved because of the priority issue.  Besides, you're relinquishing control, that means you're giving up your timeslice.  Saying that is the same as what I'm complaining about is pedantic, 1ms isn't going to give the application the appearance of not being exitable.  Use of Sleep(1) over Sleep(0) can actually make an application consistently appear more responsive and use less CPU.

See also www.bluebytesoftware.com/.../PermaLink,guid,1c013d42-c983-4102-9233-ca54b8f3d1a1.aspx and the rest of Joe Duffy's blog.

Saturday, May 17, 2008 6:31 PM by PeterRitchie

# re: Thread.Sleep is a sign of a poorly designed program.

@Denny: I would recommend using a timer.  In a Windows service,  Would recommend System.Timers.Timer.  See msdn.microsoft.com/.../system.timers.timer(VS.80).aspx.

Saturday, May 17, 2008 6:33 PM by PeterRitchie

# re: Thread.Sleep is a sign of a poorly designed program.

I have no UI.  I'm a webservice.  If your advice is never to call Sleep on a UI thread, or a thread running a message pump, I can agree with that.  I just can't agree with "Thread.Sleep is sign of a poorly designed program".

Saturday, May 17, 2008 7:43 PM by I like Sleep

# re: Thread.Sleep is a sign of a poorly designed program.

I find Sleep is very useful in following case.   -> Ur application run in the back ground say   as a window service.

-> U have a strict requirement that asks ur application not to use more than x% of CPU.

Do you find any other way than Sleep which will release the CPU for other and guarantees that ur application never uses more than x% CPU as specified.

Please comment...

Tuesday, July 22, 2008 10:46 AM by Sumit

# re: Thread.Sleep is a sign of a poorly designed program.

@Sumit:  Sleep means that the current thread has been reserved for ~x number of milliseconds.  Does that mean CPU usage is throttled?  Yes.  Does it reliably allow you to throttle CPU usage to a given %?  No, Sleep isn't that accurate; it may sleep for less time, it may sleep for more time.   But, it also means you now cannot do anything else with that thread until the time has expired.  This also means anything dependant on that thread is not dependant on that amount of time.  E.g. creating a non-background thread that sleeps for 1000 ms means the application cannot exit until Sleep returns.  

You can do the same thing with EventWaitHandles, Mutexs, and have the ability to abort the wait.

If you're looking at throttling CPU usage to a specific percent then you should be looking at a managing your own work items and schedule them appropriately.  Arbitrarily pausing a thread also means that whatever resources that thread has locked stay locked.  E.g. that thread may be writing to a file; if you pause that thread in the middle of that write nothing else can write to that file--you then have a dead-lock.  If the thread hasn't written all the data to the file and what is has written isn't complete (e.g. you updated the date 01 31 2008 in a file, but only wrote out 02 (feb), you now have an invalid file (02 31 2008 is an invalid date).

Tuesday, July 22, 2008 11:40 AM by PeterRitchie

# re: Thread.Sleep is a sign of a poorly designed program.

"not dependant" == "now dependant"

Tuesday, July 22, 2008 11:55 AM by PeterRitchie

# re: Thread.Sleep is a sign of a poorly designed program.

Thanx Peter for the valuable comments....

Yes managing work items for throttling CPU usage to a specific percent is great idea. Can u please explain more in that terms (may be one more blog).

In the mean while can u pls comment on the flaws on the following design as u find.

I have a background thread which runs on an infinite loop in following manner ..                                          

while(true)

{

  // Acquire necessary lock/resource

  // Perform one well defined task

  // Release lock / resource

 Thread.Sleep(configurable_Time);

 // Just to give CPU to others so that

 // current process does not use more than specific (rough number) % of CPU

}

Wednesday, July 23, 2008 2:56 AM by Sumit

# re: Thread.Sleep is a sign of a poorly designed program.

I primarily write websites using ASP.Net (C#).  Recently I have come across the need to write a windows service that polls a SQL Server Table and does something based on the table values.  If the process is running then I do not want to polls the SQL Server table until the process is complete.  Base on examples of logic I have found pertaining to creating this service, I was lead here.  My problem is that everything I have found so far suggests using Thread.Sleep to accomplish my goal.  If this is a bad design what would be a good design for periodically polling a SQL Server table and pausing the polling to do something with the data when the appropriate values are found?  

Friday, August 15, 2008 9:29 AM by Jeff

# re: Thread.Sleep is a sign of a poorly designed program.

Everything you've found so far suggests using Thread.Sleep?  Scary.

If you want to periodically perform some logic I recommend using a System.Timers.Timer object.  The System.Timers.Timer.Elapsed event handler would be the place to put the code to query the table.  You can pause the timer while you're doing your processing with the System.Timers.Timer.Enabled property.  Alternatively you could use System.Timers.Timer.Stop to pause the timer and System.Timers.Timer.Start to restart it (you're intentions are a little more clear using Stop/Start).

Friday, August 15, 2008 12:35 PM by PeterRitchie

# Tired of spam

Is this gonna end someday??

Wednesday, August 27, 2008 8:42 AM by accipmebpaped

# re: Thread.Sleep is a sign of a poorly designed program.

Is what going to end?

Wednesday, August 27, 2008 8:58 AM by PeterRitchie

# re: Thread.Sleep is a sign of a poorly designed program.

I am designing a program which has to reliably communicate with an Opto22 PAC on a rack.

The old regime made use of Thread.Sleep() to force the program to wait some time before checking to see if there was a message in the bytes received back from the Opto.

Trying to divorce myself of this method, I naively thought I would make a synchronizer class which essentially is a System.Timers.Timer which will count at a certain sampleRate for a certain duration.

Using a 1000 ms duration, I noticed that for higher sampleRates (~100-1000 ms), the delay is close enough to a second.  For 1 ms sampleRates though, it takes over 10 seconds.

Essentially, my question is whether there is a way to reliably pause for definate amounts of time or whether my communications design is inherently flawed if it relies on such pauses to keep things syncrhonized?

Thanks for all the help,

- Dan

Wednesday, August 27, 2008 7:28 PM by Daniel Bank

# re: Thread.Sleep is a sign of a poorly designed program.

You are both right and wrong. I agree and disagree. You should never use thread sleep for timing a thread or an application in Windows. [It is a different matter you can still use delay(n) in DOS, and that works perfectly too, but DOS is not a multi tasking OS]. I have been writing applications that need real time hardware interfacing in C, Turbo Pascal, VC++ and Delphi. In Windows, there is nothing else available for a thread to wait, anything else actually slows down systems. Also, do not forget the fact that all non multi threaded windows applications WITH AN EVENT DRIVEN UI use an infinite loop with a sleep - awake - check if something happened/needs to happen sequence. A straight Windows UI application (maybe in VB or Delphi) sleeps and awakes around 18 times a second to see if a user pressed something or some action has to take place. This is the same across all OSes, and it is nothing new. .NET is known to be thread heavy - especially kernel round trips and mutexes. I do not know whether this is true, but I have heard people say that .NET automatically enforces mutexes in the background without developers being aware of it if there are two or more threads (accessing a common variable) and a DLL assembly in the program, even if only one thread is "writing" to the variable and the others are only "reading" from it. I have been told this happens whenever there is a DLL present, but not on other occasions. I have also been told it becomes very difficult to write proper device drivers using C# and .NET, and that is one of the main reasons for Vista's unpopularity - device drivers not working for a variety of printers and other hardware devices as they were written using C# and .NET. I do see that C# is a nice language and we are starting a multi threaded hardware interfacing project in C# and there are DLLs too. This project has only one thread updating some common variables and other threads reading from it. The prototype in Delphi works fine, and I am sure that VC++ will also work the way we intend it to. It is .NET which is the unknown here, especially when people tell me that it enforces mutexes in the background without us being aware of it. I am just hoping and praying it is not true. I do like C# as a language, but I don't want .NET coming in the way.

Thursday, August 28, 2008 7:39 AM by AMS

# re: Thread.Sleep is a sign of a poorly designed program.

There are lots of ways in Windows to get a thread to wait that doesn't affect performance.  Most of them deal with thread synchronization.  And that's what you're effectively doing when you think you need to use Sleep().  What you want is to block the thread until something else happens, it's just most people only see the time-out part of that "something else" when they should also see that they need to be able to unblock that thread at any time for it to terminate.

For example, an alternative to Sleep:

static void ThreadEntry(object parameter)

{

EventWaitHandle eventWaitHandle = parameter as EventWaitHandle;

if (eventWaitHandle == null) return;

if (false == eventWaitHandle.WaitOne(1000))

{

Trace.WriteLine("doing something in background thread");

// do something every second

}

// another thread signaled eventWaitHandle

// effectively asking the thread to exit

Trace.WriteLine("exiting thread");

}

I don't know where you got your other misinformation; but, .NET does not enforce mutexes in the background to synchronize common variables, it's not difficult to write drivers in C#/.NET--it's currently impossible,

Thursday, August 28, 2008 8:57 AM by PeterRitchie

# re: Thread.Sleep is a sign of a poorly designed program.

Jeff, do you have multiple threads polling the SQL table or just one thread?

I came across a problem in Thread.Sleep that if all threads becomes sequesntial instead of Parallel.

Tuesday, November 04, 2008 4:54 AM by Anuj

Leave a Comment

(required) 
(required) 
(optional)
(required)