Why is Thread.Sleep so harmful Why is Thread.Sleep so harmful multithreading multithreading

Why is Thread.Sleep so harmful


The problems with calling Thread.Sleep are explained quite succinctly here:

Thread.Sleep has its 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 numberof timeslices (or thread quantums) that can occur within nmilliseconds.The length of a timeslice is different on different versions/types ofWindows and different processors and generally ranges from 15 to 30milliseconds. This means the thread is almost guaranteed to block formore than n milliseconds. The likelihood that your thread willre-awaken exactly after n milliseconds is about as impossible asimpossible can be. So, Thread.Sleep is pointless for timing.

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

The preferred solution: WaitHandles

The most-made-mistake is using Thread.Sleep with a while-construct (demo and answer, nice blog-entry)

EDIT:
I would like to enhance my answer:

We have 2 different use-cases:

  1. We are waiting because we know aspecific timespan when we should continue (use Thread.Sleep, System.Threading.Timer or alikes)

  2. We are waiting because some condition changes some time ...keyword(s) is/are some time! if the condition-check is in our code-domain, weshould use WaitHandles - otherwise the external component shouldprovide some kind of hooks ... if it doesn't its design is bad!

My answer mainly covers use-case 2


SCENARIO 1 - wait for async task completion: I agree that WaitHandle/Auto|ManualResetEvent should be used in scenario where a thread is waiting for task on another thread to complete.

SCENARIO 2 - timing while loop: However, as a crude timing mechanism (while+Thread.Sleep) is perfectly fine for 99% of applications which does NOT require knowing exactly when the blocked Thread should "wake up*. The argument that it takes 200k cycles to create the thread is also invalid - the timing loop thread needs be created anyway and 200k cycles is just another big number (tell me how many cycles to open a file/socket/db calls?).

So if while+Thread.Sleep works, why complicate things? Only syntax lawyers would, be practical!


I would like to answer this question from a coding-politics perspective, which may or may not be helpful to anyone. But particularly when you're dealing with tools that are intended for 9-5 corporate programmers, people who write documentation tend to use words like "should not" and "never" to mean "don't do this unless you really know what you're doing and why".

A couple of my other favorites in the C# world are that they tell you to "never call lock(this)" or "never call GC.Collect()". These two are forcefully declared in many blogs and official documentation, and IMO are complete misinformation. On some level this misinformation serves its purpose, in that it keeps the beginners away from doing things they don't understand before fully researching the alternatives, but at the same time, it makes it difficult to find REAL information via search-engines that all seem to point to articles telling you not to do something while offering no answer to the question "why not?"

Politically, it boils down to what people consider "good design" or "bad design". Official documentation should not be dictating the design of my application. If there's truly a technical reason that you shouldn't call sleep(), then IMO the documentation should state that it is totally okay to call it under specific scenarios, but maybe offer some alternative solutions that are scenario independent or more appropriate for the other scenarios.

Clearly calling "sleep()" is useful in many situations when deadlines are clearly defined in real-world-time terms, however, there are more sophisticated systems for waiting on and signalling threads that should be considered and understood before you start throwing sleep() into your code, and throwing unnecessary sleep() statements in your code is generally considered a beginners' tactic.