0

I mainly followed what was discussed in the second answer to this thread. I want to run a program that will continuously check for CPU usage above 5% for 10 seconds and alert me every time it happens.

How to get the CPU Usage in C#?

And my code is as follows:

static void Main(string[] args)
{
    Console.WriteLine("Checking for CPU usage");
    int totalhits = 0;
    float cpuPercent = getCPUValue();
    while (true)
    {
        if (cpuPercent >= 5)
        {
            totalhits += 1;
            if (totalhits == 10)
            {
                Console.WriteLine("Alert Usage has exceeded");
                Console.WriteLine("Press Enter to continue");
                Console.ReadLine();
                totalhits = 0;
            }
        }
        else
        {
            totalhits = 0;
        }
    }
}

private static float getCPUValue()
{
    PerformanceCounter cpuCounter = new PerformanceCounter();
    cpuCounter.CategoryName = "Processor";
    cpuCounter.CounterName = "% Processor time";
    cpuCounter.InstanceName = "_Total";

    float firstValue = cpuCounter.NextValue();
    System.Threading.Thread.Sleep(50);
    float secondValue = cpuCounter.NextValue();
    return secondValue;
}

My problem is that it never hits that threshold and if I take out the totalhits = 0; statement inside the innermost if statement then it hits the threshold in less than 5 seconds.

What am I doing wrong?

Community
  • 1
  • 1
  • 1
    float cpuPercent = getCPUValue(); should be inside your loop.. – Tony Hopkinson Jun 23 '14 at 16:39
  • You are getting the CPU % and then spinning in a loop checking that forever. Also, each loop iteration is not '1 second' you need to sleep the thread to emulate something like that. – TheNorthWes Jun 23 '14 at 16:41

2 Answers2

1

First of all the

float cpuPercent = getCPUValue();

line should be inside the loop. Otherwise you will read the CPU usage only once. and will iterate over the same value.

You should create Only one PerformanceCounter object, and just call cpuCounter.NextValue() again and again inside the loop. DON'T create the same CPU PerformanceCounter in every iteration.

   PerformanceCounter counter = new PerformanceCounter("Processor", "% Processor Time", "_Total");
   while (true)
   {
       float cpuPercent = counter.nextValue();
       if (cpuPercent >= 5)
       {
           totalhits += 1;
           if (totalhits == 10)
           {
               Console.WriteLine("Alert Usage has exceeded");
               Console.WriteLine("Press Enter to continue");
               Console.ReadLine();
               totalhits = 0;
           }
       }
       else
       {
           totalhits = 0;
       }
   }

As stated in MSDN

To obtain performance data for counters that required an initial or previous value for performing the necessary calculation, call the NextValue method twice and use the information returned as your application requires.

So you should call the cpuCounter.NextValue() twice (with about a 1 second delay between the calls) to start getting correct CPU Usage results.

BTW, You should wait about a 1 second between each read operation from the CPU PerformanceCounter (to ensure update).

As shown in this post Retriving Accurate CPU Usate In C#

m1o2
  • 1,549
  • 2
  • 17
  • 27
  • Okay, I changed it to what you suggested and my program hits the threshold after 23 seconds or so, not 10. After I press enter to do it again, it doesn't reach the threshold. – user3757114 Jun 23 '14 at 17:01
  • @user3757114 I guess your PC is really fast. As I added in my answer, you should wait about a one second between each iteration. And did you thought about the possibility that your CPU % will stay above 5% for majority of the time? – m1o2 Jun 23 '14 at 17:08
  • Should I call both of the .NextValue() functions in the loop or one outside and then the other inside? – user3757114 Jun 23 '14 at 19:34
  • @user3757114 It could be done in both ways. Though, I suggest to do it outside of the loop, with the initializing of the PerformanceCounter. You can create a new method that will create a new PerformanceCounter, initialize it, perform the first two .NextValue() calls and then return the counter. save the returned PerformanceCounter object in the cpuCounter variable before the loop, and then use it with .NextValue() inside of it as usuall. – m1o2 Jun 23 '14 at 23:02
0

Use the DispatcherTimer as stated in the below msdn and get the results as you needed.

DispatcherTimer

Ramesh
  • 376
  • 2
  • 6
  • 11
  • It is a very bad idea to do this on the UI thread. If it is needed to use timer, then you could pull it off with System.Threading.Timer or with System.Timers.Timer – m1o2 Jun 23 '14 at 23:06