5

I know this might be a bit of a 'silly' question, but sometimes, I just want to loop until a condition is false but I don't like keeping the loop empty. So instead of:

Visible = true;
while(IsRunning)
{
}
Visible = false;

I usually prefer:

while(IsRunning)
{
    Visible = true;
}
Visible = false;

However, I'm a bit concerned about what exactly happens at the line Visible = true;. Does the Runtime keep executing that statement even though it's redundant? Is it even advisable to do it this way? Many 'code-enhancements' plugins don't like empty while loops, and I don't really understand why.

SO:

  • Is there anything wrong with having an empty while loop?

  • Does having a loop such as shown above have any performance effects?

Thanks!

Chibueze Opata
  • 9,856
  • 7
  • 42
  • 65
  • 3
    It is called a busy-wait loop, it is usually used to wait for some condition to become true and false before proceeding with the program – Hunter McMillen Aug 04 '12 at 14:11
  • i don't understand why you'd even do this. i'm assuming IsRunning would be set by another thread... so why wouldn't you just spin off another thread and Join() it? that's clearer and blocks just the same. – Mike Corcoran Aug 04 '12 at 14:14
  • 1
    Some early computer designs had a dedicated processor instruction for code like this: HCF. Hold and Catch Fire. – Hans Passant Aug 04 '12 at 14:18
  • 8
    An empty loop checking for a condition is like a child constantly asking "Are we there yet? Are we there yet? Are we there yet?" on a car trip. You want your program, and the kid, to just go to sleep until the condition becomes true. – Wyzard Aug 04 '12 at 14:28
  • I'm curious, do async waits exhibit this behaviour in any regards? I encountered a similar problem recently and the issue seemed to be coming from the async line.. – Chibueze Opata Jun 20 '22 at 14:47

4 Answers4

7

This is called busy or spin waiting.

The main problem is, that you are blocking the thread, that is running this while loop. If this thread is GUI thread, then it will result in freezing and unresponsible GUI. And yes, this results in loss of performance, because neither compiler, nor OS can know if they can somehow optimize this while loop.

Just try making single loop like this and see how one core of your CPU is running at 100%.

The right way to do this is to use asynchronous programming, where your code gets notified, either by event or language construct (like await) when the previous operation finished running.

But it is usually used in low-level systems or languages. .NET 4.0 introduces SpinWait construct, that serves as efficient threading sychnronization.

And in relation to your question. I believe neither should be used. They are both problematic for both debugging, performance and clarity of code.

Euphoric
  • 12,645
  • 1
  • 30
  • 44
  • not necessarly. you can also do something ´while(DoSomething) {}´ which won't put processor power in spinning. The DoSomething could for example be Cleanup ressources at end of a step, and it should not continue until cleaned up. Some ConcurrentThingies from .net does not give an iterator, so a TryTake or something can be within the while expression . There are some samples where you use a while, but the expression itself does something. So it will only need the power to process... – Offler Jul 18 '13 at 14:57
  • @Offler Yo mean DoSomething() could be a method? Because that is not what question is about. – Euphoric Jul 18 '13 at 15:04
  • Yep, just because of the two sentences `Many 'code-enhancements' plugins don't like empty while loops, and I don't really understand why.` and `Is there anything wrong with having an empty while loop?` which are more generic. Even 'IsRunning' would be a property which in fact can do a lot of things with Threads/sleeps and so on in it's getter method, so that none can really tell if the CPU will go to 100% .. – Offler Jul 19 '13 at 09:18
1

It's not a good idea to do this. Start up the application, and when it enters this loop, take a look at the CPU usage in the task manager. You'll notice that one of the CPU cores will be running at full capacity. This means that energy is being wasted, and some other programs that may need to execute would not have as much CPU time as they could.

There are several ways around this. The simplest solution here is to put the thread to sleep for some number of milliseconds within each loop pass, like this:

Visible = true;
while(IsRunning)
{
    Thread.Sleep(50 /* millisec */);
}
Visible = false;

A better solution would depend on what exactly your program is doing. If it's loading something in another thread, it may be better to either use AutoResetEvent, or through locking, or other thread synchronization mechanism.

ikh
  • 2,336
  • 2
  • 19
  • 28
1

Don't do it in main (UI thread). Try to find or make event (for ex. IsRunningChanged).

If you are need to wait something in thread it is better to use EventWaitHandle http://msdn.microsoft.com/en-us/library/system.threading.eventwaithandle.eventwaithandle.aspx

But if you need to wait for bool value you can do

while(IsRunning)
{
    Thread.Sleep(10);
}
oxfn
  • 6,590
  • 2
  • 26
  • 34
gabba
  • 2,815
  • 2
  • 27
  • 48
1

Well..

  • Yes an empty while loop would generally be seen as a bad thing, though there are a few useful cases too.
  • Yes the CPU will execute your redundant statement
  • No, you should not do something like that. It uses 100% of the CPU and that is not useful.

There are alternate solutions, but without knowing your program it's hard to advise. You might however want to look into IPC and generally use blocking methods (call them in separate threads) instead of non-blocking.

Blocking methods pause your thread and give control back to the operating system which will (hopefully) do something useful with the CPU time, like putting parts of the CPU to sleep, saving power and reducing heat output.

dualed
  • 10,262
  • 1
  • 26
  • 29