What is the reason for “while(true) { Thread.Sleep }”?

前端 未结 7 1807
自闭症患者
自闭症患者 2021-02-09 05:43

I sometimes encounter code in the following form:

while (true) {
  //do something
  Thread.Sleep(1000);
}

I was wondering if this is considered

相关标签:
7条回答
  • 2021-02-09 05:44

    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();
         }
    }
    

    Is the so-called 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.

    When I would use a while loop or something like the AutoResetEvent approach?

    When to use while loop...

    ...when you need to execute code while waiting the program to end.

    When to use 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.

    0 讨论(0)
  • 2021-02-09 05:45

    It really depends on that //do something on how it determines when to break out of the loop.

    In general terms, more appropriate way to do it is to use some synchronization primitive (like ManualResetEvent) to wait on, and the code that processes and triggers the break of the loop (on the other thread) to signal on that primitive. This way you don't have thread wasting resources by being scheduled in every second to do nothing, and is a much cleaner way to do it.

    0 讨论(0)
  • 2021-02-09 05:59

    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:

    • If the code is waiting for a change in the file system, use a FileSystemWatcher.
    • If the code is waiting for a thread or process to complete, or a network event to occur, use the appropriate synchronization primitive and 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.

    0 讨论(0)
  • 2021-02-09 06:01

    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.

    0 讨论(0)
  • 2021-02-09 06:02

    There are better ways to keep the Azure Service and exit when needed.

    Refer:

    1. http://magnusmartensson.com/howto-wait-in-a-workerrole-using-system-timers-timer-and-system-threading-eventwaithandle-over-system-threading-thread-sleep
    2. http://blogs.lessthandot.com/index.php/DesktopDev/MSTech/azure-worker-role-exiting-safely/
    0 讨论(0)
  • 2021-02-09 06:05

    If you use while(true) you have no programmatic means of ending the loop from outside the loop.

    I'd prefer, at least, a while(mySingletonValue) which would allow us to switch the loop as needed.

    An additional approach would be to remove the functional behavior from the looping behavior. Your loop my still be infinite but it calls a function defined elsewhere. Therefore the looping behavior is completely isolated to what is being executed by the loop:

    while(GetMySingletonValue())
    {
        someFunction();
    }
    

    In this way your singleton controls the looping behavior entirely.

    0 讨论(0)
提交回复
热议问题