Avoiding high processor load in long running loops

Keep processor not overloaded with long running loops

When having a long running loop which you are not sure when it is going to end you will probably have to create a loop in a separate loop and on every iterration you will check whether some condition is true and exit the loop.

Let's say you want to execute some piece of code after some specific time, let's say after one minute or everyday at specific time (common scenario in windows services). You can do it really simple with Timer class and just few lines of code as the code below.

static void Main()
{
System.Timers.Timer timer = new System.Timers.Timer(60000);
timer.Elapsed = timer_Elapsed;
Console.ReadLine();
}
static void timer_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
        {
            //Time interval expired
        }
    

When you run this piece of code and check usage of CPU with ProcessExplorer or some other tool, you'll see that it barely uses the CPU althought it is running in a loop in background.

 Long Loop Timer

For the example purposes I will write small replica of Timer functionality. This functionality can be easily reproduced using long running loop.

new System.Threading.Thread(() =>
            {
                DateTime startTime = DateTime.Now;
                int interval = 60000;
                bool keepChecking = true;
                while (keepChecking)
                {
                    if (DateTime.Now > startTime.AddMilliseconds(interval))
                    {
                        keepChecking = false;
                        //Time interval expired
                    }
                }
            }).Start();
    

If you run this code and check CPU usage you will see heavier load on the CPU since it is constantly looping and checking current time.

Long Loop

It makes sense since your code is constantly working something. The thing is you do not have to check the time on every loop iteration, you can let CPU work with some other process for some time. If you put your thread that runs the loop for sleep at least for 1 millisecond you will see the difference. You can even use lnger sleep period, if it is not important for your logic to have some delay for et's say 10 milliseconds, which will even more utilize CPU load.

new System.Threading.Thread(() =>
            {
                DateTime startTime = DateTime.Now;
                int interval = 60000;
                bool keepChecking = true;
                while (keepChecking)
                {
                    if (DateTime.Now > startTime.AddMilliseconds(interval))
                    {
                        keepChecking = false;
                        //Time interval expired
                    }
                    System.Threading.Thread.Sleep(1);
                }
            }).Start();
    

Long Loop Sleep

Simple putting your loop thread to sleep will utilize CPU usage.

References

Disclaimer

Purpose of the code contained in snippets or available for download in this article is solely for learning and demo purposes. Author will not be held responsible for any failure or damages caused due to any other usage.


About the author

DEJAN STOJANOVIC

Dejan is a passionate Software Architect/Developer. He is highly experienced in .NET programming platform including ASP.NET MVC and WebApi. He likes working on new technologies and exciting challenging projects

CONNECT WITH DEJAN  Loginlinkedin Logintwitter Logingoogleplus Logingoogleplus

JavaScript

read more

SQL/T-SQL

read more

Umbraco CMS

read more

PowerShell

read more

Comments for this article