Why the CPU Performance Counter Kept Reporting 0% CPU Usage

Why the cpu performance counter kept reporting 0% cpu usage?

The first iteration of he counter will always be 0, because it has nothing to compare to the last value. Try this:

var cpuload = new PerformanceCounter("Processor", "% Processor Time", "_Total");
Console.WriteLine(cpuload.NextValue() + "%");
Console.WriteLine(cpuload.NextValue() + "%");
Console.WriteLine(cpuload.NextValue() + "%");
Console.WriteLine(cpuload.NextValue() + "%");
Console.WriteLine(cpuload.NextValue() + "%");

Then you should see some data coming out. It's made to be seen in a constant graph or updated scenario...that's why you don't come across this problem often.

Here's the MSDN reference:

The method nextValue() always returns
a 0 value on the first call. So you
have to call this method a second
time.

Why does this performance counter always return zero?

From MSDN:

If the calculated value of a counter depends on two counter reads, the first read operation returns 0.0. Resetting the performance counter properties to specify a different counter is equivalent to creating a new performance counter, and the first read operation using the new properties returns 0.0. The recommended delay time between calls to the NextValue method is one second, to allow the counter to perform the next incremental read.

So from that, I'd say the calculated value of the "% Processor Time" counter depends on two counter reads, so the first you're seeing is 0.0, per the docs.

I tested it using their suggestion of waiting a second between reads. I got 0.0 every time on the first read, but then positive values afterwards.

using (PerformanceCounter pfc = new PerformanceCounter("Processor", "% Processor Time", "_Total"))
{
MessageBox.Show(pfc.NextValue().ToString());
Thread.Sleep(1000);
MessageBox.Show(pfc.NextValue().ToString());
Thread.Sleep(1000);
MessageBox.Show(pfc.NextValue().ToString());
}

Performance counter CPU usage for current process is more than 100

This (somewhat related) question suggests using the System.Diagnostics.Process.TotalProcessorTime and System.Diagnostics.ProcessThread.TotalProcessorTime properties instead, for low overhead and easy implementation.

(Edit: Here's an article explaining how to use the properties, as well.)

Also, it looks like you're not waiting long enough between calls to "_processTimeCounter.NextValue()." As per the documentation, you're supposed to wait at least 1 second. Not sure if that would cause your strange numbers or not.

Retrieve Cpu usage asynchronously in C#

Unfortunately, dotnetfiddle won't allow me PerformanceCounters, but this should work anyway:

public class Helper // Of course, you do not necessarily need an extra class ...
{
// Lazy Pattern: Will create an instance on first usage.
private static Lazy<PerformanceCounter> CpuPerformance = new Lazy<PerformanceCounter>(() => {
// this will be used as factory to create the instance ...
// 1. create counter
PerformanceCounter pc = new PerformanceCounter("Processor Information", "% Processor Time", "_Total");
// "warm up"
pc.NextValue();
Thread.Sleep(1000);
// return ready-to-use instance
return pc;
// ^^ this will be executed only _once_.
});

// Read-Only Property uses Lazy to ensure instance exists, then use it.
public static float CpuTimeInPercent {
get { return CpuPerformance.Value.NextValue(); }
}
}

Usage:

Console.WriteLine("Performance: {0}%", Helper.CpuTimeInPercent);

Get CPU usage of process with PerformanceCounter

It's okay, because NextValue always return 0 when you call it first time.

For fix this error you can call NextValue function twice after creation PerformanceCounter object (durty hack).

PerformanceCounter.NextValue() returns constant value for CPU load

   new PerformanceCounter("Process", "% Processor Time", "_Total");

Yes, the processor time taken by the _Total number of processes, including the fake "System Idle Process" you see back in Task Manager, will always add up to 400% on a 4 core machine.

You'll probably like the number better if you change "Process" to "Processor". If you want to match the value that Task Manager displays then you need to change "Process" to "Processor Information". A new category that tries to generate a more realistic number that's compensated for a processor with turbo boost, machines with NUMA nodes and the lower perf you get from hyper-threads. You'll want to read this blog post for the nitty-gritty.

Trying To Pull CPU & Network Usage Information From Performance Monitor

You'll need at least two reads for every counter, at least a second apart to get a usable reading.

Rearrange as needed but you would need to do something like this:

private static IEnumerable<String> GetProcessStatistics(String[] processesTosearch)
{
Process[] processList = Process.GetProcesses();

foreach (string process in processesTosearch)
{
foreach (Process p in processList)
{
if (p.ProcessName == process)
{
StringBuilder sb = new StringBuilder();
PerformanceCounter CPUperformanceCounter = new PerformanceCounter("Process", "% Processor Time", p.ProcessName);
PerformanceCounter NETWORKperformanceCounter = new PerformanceCounter("Process", "IO Data Operations/Sec", p.ProcessName);

// set a baseline
CPUperformanceCounter.NextValue();
NETWORKperformanceCounter.NextValue();

Thread.Sleep(1000);

double cpuData = CPUperformanceCounter.NextValue();
double networkData = NETWORKperformanceCounter.NextValue();

sb.AppendLine("ID: " + p.Id.ToString());
sb.AppendLine("NAME: " + p.ProcessName);
sb.AppendLine("CPU USAGE: " + cpuData);
sb.AppendLine("RAM USAGE: " + ConvertToReadableSize(p.PrivateMemorySize64));
sb.AppendLine("NETWORK USAGE: " + networkData);
yield return sb.ToString();
}
}
}
}


Related Topics



Leave a reply



Submit