So, I have created an automation script performs a task every minute, on the minute (I want the task to be ran at the :00 second of each minute). As a test, the function that I am calling every minute just writes to console and to a text file that it has ran and at which time it has ran.
I don't know anything about resource usage of apps and how to reduce it, but for some reason this application is using around 17% of my CPU on an i7 8750h cpu.
The entire code for the script is as follows:
Logger.WriteLine("Program starting... @ " DateTime.Now.ToString("HH:mm:ss"));
static void TestTask()
{
string currentTime = DateTime.Now.ToString("HH:mm:ss");
Logger.WriteLine("Test task ran at: " currentTime);
}
// This currently runs forever, as there is no boolean condition evaluated to false to break the while loop (which is expected behavior)
while (true)
{
// Evyer minute on the minute
if (DateTime.Now.Second == 0)
{
TestTask();
Thread.Sleep(1000);
}
}
The Logger.WriteLine class is a custom class I created that essentially acts the same as Console.WriteLine as it prints the string to the console, but it also adds it to a stringbuilder that then gets written using stringwriter to a .txt file on my desktop. Could this be the issue?
I also tried creating the exact same program in Python, and it uses the same amount of CPU usage. Both .exe versions of the program use about 5mb of memory which is fine for me, but its just the CPU usage that I would like to reduce.
Anyone know anything I could do? Thanks!
CodePudding user response:
To answer the question in the title
The code you posted will use pretty much 100% of a CPU core because for 59 out of the 60 seconds in a minute, all it does is evaluate whether true == true
and whether the second component of DateTime.Now is 0, as fast as possible. The call to Thread.Sleep(1000)
only occurrs in the 0th second.
A Core i7-8750H is a 6 core CPU, so divide 100% by 6 and you get (roughly) 17% overall utilisation. The result was the same in Python because the logic is exactly the same.
As for what you ought to do about it
There are numerous ways to accomplish the goal of a task that runs once a minute depending on the system you're working with. On Windows, you could use Windows Task Scheduler, on Unix-likes you could use cron, on macOS you could use launchd. If this is a sub-component of an app that needs to run in the background of that app, perhaps start here. Thread.Sleep()
is not the recommended way to go about this.
CodePudding user response:
It's using up so much of your CPU because it's constantly looping round checking if it's the 1st second of the minute.
Thread.Sleep
is only hit on the 1st second of each minute.
Moving Thread.Sleep
outside of the if statement (but still within the while loop) and reducing the duration would improve it:
while (true)
{
// Every minute on the minute
if (DateTime.Now.Second == 0)
{
TestTask();
}
Thread.Sleep(500);
}
It would be better yet to use a wait or a timer.