Firstly I am not asking the same question as C# - Alternative to Thread.Sleep?, or Alternative to Thread.Sleep in C#?. I don't think I am using it incorrectly and need a genuine alternative for specific situations.
During a code analysis run I saw a surprising violation coming up:
Usage of Thread.Sleep() is a sign of flawed design.
This violation leads to Peter Richie's article on why exactly this constitutes bad design.
We all know thread creation is expensive and blocking in threads means contention on the pool. We also know that each thread will allocate a meg of memory so it should have a short lifespan, blocking on the UI is evil, using sleep for timing is unreliable etc etc etc. Which leads me to my point, if you really need to perform a sleep, what should you be using if not Thread.Sleep?
Peter goes on to mention that a zero sleep is the only correct use of Thread.Sleep effectively giving up the thread's timeslice and allowing other threads to process. And then even more scary is that this is only a because of limitations on unmanaged threads and if re-implemented in the CLR will create side effects of using Thread.Sleep in your applications. All the points on common bad usage are, in fact, good examples of bad usage.
I have the following situations in production code that uses Thread.Sleep quite successfully:
- Waiting for a file lock to be relinquished by the operating system (catch file lock problems, wait for a second, try again, give up after a while).
- Killing a process and waiting for it not to show up in the process list (kill it, check it's not running, wait for a second, check it not still running, force it closed).
- Waiting for copy buffers to flush (check a file size, try to access it, wait, check if size has changed).
Without using Thread.Sleep in situations like these, what other options do I have? Tight loops tend to make things worse and I don't believe this makes it's usage a "design flaw" especially since nothing is on the UI and only in background threads. It is just the nature of software to wait for other things in a multi-threaded environment with external factors affecting your code, sometimes you need to wait...