Question

I have read up on some of the other CPU usage questions here, but I'm stuck with why my code isn't working.

I have the code in a separate Class named "ComputerPerformance" from From1.

class
{
   private string cCpuUtilization;

   public void cpuUtilization()
   {
      try
      {
         PerformanceCounter cpuCounter;
         cpuCounter = new PerformanceCounter();
         cpuCounter.CategoryName = "Processor";
         cCpuUtilization = cpuCounter.NextValue() + "%";
      }
      catch(System.InvalidOperationException e)
      {
      }
   }

   public String getCPUUtilization()
   {
      return cCpuUtilization;
   }
}

The code runs fine, but I am getting nothing as an output...

Update

The code now looks like this:

PerformanceCounter cpuCounter = new PerformanceCounter();
cpuCounter.CategoryName = "Process";
cpuCounter.CounterName = "Private Bytes";
cpuCounter.InstanceName = "Explorer";
cCpuUtilization = cpuCounter.NextValue().ToString() + "%";

My problem now is it is returning the value: 6.728499E+07% all the time... Any ideas why this would be?

Was it helpful?

Solution

Per your update of why you get 6.728499E+07%, well you are reading the memory Private Bytes usage not CPU Usege. So the number being returned is the number of private bytes used by explorer (about 67,284,990 bytes). If you don't want scientfic notation for those large numbers pass in a number formatting string to ToString

cCpuUtilization = cpuCounter.NextValue().ToString("N0") + " bytes"; //Should now print "67,284,990 bytes"

OTHER TIPS

The code runs fine, but I am getting nothing as an output...

No, the code doesn't run fine:

  1. You're never being told about the error because of your exception handling.
  2. If the code runs fine then it would produce output.

Your code explicitly ignores any error that results in an InvalidOperationException. Exceptions are there for a reason, usually to tell you that there is something seriously wrong. The only time you should use should ignore them is when you really, really don't care that an exception has occurred.

In your code you set CategoryName to indicate which group of counters you're looking at, but never set the CounterName property to specify which counter to use. And in the case of the Processor group, since there are potentially multiple processors.

Next problem, the first result you get from cpuCounter.Nextvalue() is groing to be 0.0. Always. The NextValue method gets a sample from the counter and compares it to the last sample to calculate an actual value. Necessarily this requires two calls to NextValue with a delay between in order to get a valid result. That delay should be at least a second.

Here's some code that fixes a few of the problems:

public class CPUTime : IDisposable
{
    private PerformanceCounter counter;
    private DateTime lastcheck;
    private float lastvalue;

    public float Value
    {
        get
        {
            if ((DateTime.Now - lastcheck).TotalMilliseconds > 950)
            {
                lastvalue = counter.NextValue();
                lastcheck = DateTime.Now;
            }
            return lastvalue;
        }
    }

    public CPUTime()
    {
        counter = new PerformanceCounter("Processor", "% Processor Time", "_Total", true);
        counter.NextValue();
        lastcheck = DateTime.Now;
    }

    ~CPUTime()
    {
        Dispose();
    }

    public void Dispose()
    {
        if (counter != null)
        {
            counter.Dispose();
            counter = null;
        }
    }

    public override string ToString()
    {
        return string.Format("{0:0.00}%", Value);
    }
}

If that's not fast enough for you - it only updates once per second, after all - then you'll need to use the GetSystemTimes API call and do your own calculations. It still needs two samples, but you can call it much more frequently and get reasonable results.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top