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 withinn
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 thann
milliseconds. The likelihood that your thread will
re-awaken exactly aftern
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:
We are waiting because we know a
specific timespan when we should continue (useThread.Sleep
,System.Threading.Timer
or alikes)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:
- 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) - 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
All Possible Array Initialization Syntaxes
Parse String to Datetime in C#
Should 'Using' Directives Be Inside or Outside the Namespace
Nesting Await in Parallel.Foreach
How to Create a Dropdownlist from an Enum in ASP.NET MVC
How To: Execute Command Line in C#, Get Std Out Results
Async/Await - When to Return a Task VS Void
How to Turn a C# Object into a Json String in .Net
Best Way to Parse Command Line Arguments in C#
How to Get the Path of the Assembly the Code Is In
Pass Method as Parameter Using C#
Linq'S Distinct() on a Particular Property
How to Convert a Unix Timestamp to Datetime and Vice Versa
Addtransient, Addscoped and Addsingleton Services Differences