I sometimes encounter code in the following form:
while (true) {
//do something
Thread.Sleep(1000);
}
I was wondering if this is considered good or bad practice and if there are any alternatives.
Usually I "find" such code in the main-function of services.
I recently saw code in the "Run" function in a windows azure worker role which had the following form:
ClassXYZ xyz = new ClassXYZ(); //ClassXYZ creates separate Threads which execute code
while (true) {
Thread.Sleep(1000);
}
I assume there are better ways to prevent a service (or azure worker role) from exiting. Does anyone have a suggestion for me?
Thread. sleep causes the current thread to suspend execution for a specified period. This is an efficient means of making processor time available to the other threads of an application or other applications that might be running on a computer system.
Thread. sleep() is inaccurate. How inaccurate depends on the underlying operating system and its timers and schedulers. I've experienced that garbage collection going on in parallel can lead to excessive sleep.
One of the way to achieve synchronization, implement wait is by calling Thread. sleep() function however, it is not recommended because this is not very stable and unreliable. The time has to be specified in milliseconds.
A thread is in exactly one of the 5 (+1 -- 2 for WAITING ) states at any point of time. Thread. sleep(3000); and thus puts itself into sleep for 3 secs.
Well when you do that with Thread.Sleep(1000)
, your processor wastes a tiny amount of time to wake up and do nothing.
You could do something similar with CancelationTokenSource.
When you call WaitOne()
, it will wait until it receives a signal.
CancellationTokenSource cancelSource = new CancellationTokenSource();
public override void Run()
{
//do stuff
cancelSource.Token.WaitHandle.WaitOne();
}
public override void OnStop()
{
cancelSource.Cancel();
}
This will keep the Run() method from exiting without wasting your CPU time on busy waiting.
If you see code like this...
while (true)
{
//do something
Thread.Sleep(1000);
}
It's most likely using Sleep()
as a means of waiting for some event to occur — something like user input/interaction, a change in the file system (such as a file being created or modified in a folder, network or device event, etc. That would suggest using more appropriate tools:
FileSystemWatcher
.WaitOne()
, WaitAny()
or WaitAll()
as appropriate. If you use an overload with a timeout in a loop, it gives you cancelability as well.But without knowing the actual context, it's rather hard to say categorically that it's either good, bad or indifferent. If you've got a daemon running that has to poll on a regular basis (say an NTP client), a loop like that would make perfect sense (though the daemon would need some logic to monitor for shutdown events occuring.) And even with something like that, you could replace it with a scheduled task: a different, but not necessarily better, design.
An alternative approach may be using an AutoResetEvent
and instantiate it signaled by default.
public class Program
{
public static readonly AutoResetEvent ResetEvent = new AutoResetEvent(true);
public static void Main(string[] args)
{
Task.Factory.StartNew
(
() =>
{
// Imagine sleep is a long task which ends in 10 seconds
Thread.Sleep(10000);
// We release the whole AutoResetEvent
ResetEvent.Set();
}
);
// Once other thread sets the AutoResetEvent, the program ends
ResetEvent.WaitOne();
}
}
while(true)
a bad practice?Well, in fact, a literal true as while
loop condition may be considered a bad practice, since it's an unbrekeable loop: I would always use a variable condition which may result in true
or false
.
while
loop or something like the AutoResetEvent
approach?while
loop......when you need to execute code while waiting the program to end.
AutoResetEvent
approach......when you just need to hold the main thread in order to prevent the program to end, but such main thread just needs to wait until some other thread requests a program exit.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With