Why Is Thread.Sleep So Harmful

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 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.

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 a
    specific 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, we
    should use WaitHandles - otherwise the external component should
    provide some kind of hooks ... if it doesn't its design is bad!

My answer mainly covers use-case 2

Why Thread.sleep is bad to use

It's fine to use Thread.sleep in that situation. The reason people discourage Thread.sleep is because it's frequently used in an ill attempt to fix a race condition, used where notification based synchronization is a much better choice etc.

In this case, AFAIK you don't have an option but poll because the API doesn't provide you with notifications. I can also see it's a infrequent operation because presumably you are not going to create thousand tables.

Therefore, I find it fine to use Thread.sleep here. As you said, spawning a separate thread when you are going to block the current thread anyways seems to complicate things without merit.

Is it always bad to use Thread.Sleep()?

Is using Thread.Sleep bad? Generally not, if you really want to suspend the thread. But in this case you don't want to suspend the thread, you want to suspend the task.

So in this case, you should use:

await Task.Delay(minDuration);

This will not suspend the entire thread, but just the single task you want to suspend. All other tasks on the same thread can continue running.

Why using System.Threading.Thread.Sleep() is a bad practice?

One reason is that Thread.Sleep() is blocking your code from doing anything else. Recent efforts is to make blocking as least as possible. For example, node.js is a non-blocking language.

Update: I don't know about the infrastructure of Timer class in C#. Maybe it's also blocking.

You can schedule a task to check that third API every 100 ms. This way, during that 100 ms, your program can do other tasks.

Update: This analogy might help. If we compare operating system to a hospital, and compare the threads to nurses in that hospital, the supervisor (programmer) can choose a policy:

  1. Either to ask each nurse (thread) to watch one, and only one patient (a job, a task to be done), even if between each check she waits for an hour (Sleep() method)
  2. To ask each nurse to check each patient, and during the interval till next check, go on and check other patients.

The first model is blocking. It's not scalable. But in the second model, even with few nurses, you might be able to serve many patients.

what are the dangers of Thread.Sleep in Multi-Threaded code in production environment

It's not going to be explicitly or directly dangerous. It's almost certainly wasting effort, as explicitly forcing your program to not do work when it has work to do is almost never sensible.

It's also a pretty significant red flag that there's a race condition in the code and, rather than actually figure out what it is or how to fix it, the programmer simply added in Sleep calls until he stopped seeing it. If true, it would mean that the program is still unstable and could potentially break at any time if enough other variables change, and that the issue should be actually fixed using proper synchronization techniques.

How would I avoid using Thread.sleep()?

It's not very clear what your whole code does. As commented by others, knowing what MessageHandler does would add some context.

The Thread.sleep static invocation will make the current thread sleep for at least the given amount of time,

subject to the precision and accuracy of system timers and schedulers

(see API)

If your MessageHandler.getResponse invocation blocks before returning, then you probably don't need to sleep at all.

However, if this task is repeated "endlessly", you probably want to use a ScheduledExecutorService instead, and run it based on a schedule.

Bottomline, Thread.sleep is not "bad practice" per se, but you seldom need to actually use it.

Would looping Thread.Sleep() be bad for performance when used to pause a thread?

I think, based on the description, I'd do this

'Class level.
Private BytesWritten As Long = 0
Private NotPaused As New Threading.ManualResetEvent(True)

The change in the variable name is fitting since this is how it would be used

    'Method (thread) level.
While BytesWritten < [target file size]
'...write 4096 byte buffer to file...

NotPaused.WaitOne(-1)

'...do some more stuff...
End While

To make the loop pause do this

    NotPaused.Reset()

and to continue

    NotPaused.Set()

How bad is new Thread().sleep compared to Thread.sleep in terms of CPU and memory utilization?

It is just illiterate programming, simple as that. Same applies to calling any static method that way, it's not confined to Thread.sleep(). It imposes pointless space and time costs, but worse it betrays a major conceptual misunderstanding on the part of the programmer. I wouldn't devote much energy to going back and fixing all the occurrences but I would certainly do something about re-educating the personnel concerned.



Related Topics



Leave a reply



Submit