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.
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.
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();
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.
Comments for this article