Question

I've already found this question telling that the first occurrence of my PerformanceCounter is 0, so I have to call it multiple times to get the right result.

I got that to work fine - it looks like this:

public static float GetCpuUsage()
{
    var cpuCounter = new PerformanceCounter();

    cpuCounter.CategoryName = "Processor";
    cpuCounter.CounterName = "% Processor Time";
    cpuCounter.InstanceName = "_Total";

    // Prime it
    cpuCounter.NextValue();

    Thread.Sleep(500);

    return cpuCounter.NextValue();
}

However, I wish to be able to get the result from more than one PerformanceCounter without having to wait half a second for each one. I did it like this:

public static float GetCpuUsage(PerformanceCounter counter)
{
    if (counter == null)
    {
        counter = new PerformanceCounter();
        counter.CategoryName = "Processor";
        counter.CounterName = "% Processor Time";
        counter.InstanceName = "_Total";
    }

    return counter.NextValue();
}

And I call it like this:

PerformanceCounter cpuCounter = null;
PerformanceCounter memoryCounter = null;

while (_isRunning)
{
    result.Cpu = GetCpuUsage(cpuCounter);
    result.Memory = GetAvailableMemory(memoryCounter);

    // Process result

    Thread.Sleep(500);
}

I thought that was a pretty good idea - passing the same counter instance to the method every time.

However, it doesn't actually work, cpu is always 0.

It tells me there is something basic about PerformanceCounters I don't understand (and that is not addressed in the question I linked to).

What exactly is it that makes the PerformanceCounter work? Because it seems that waiting for 500 milliseconds between each NextValue call is not the only difference.

Was it helpful?

Solution

I found the reason - it was a basic .NET mistake and not something to do with PerformanceCounters. If I pass an object (in this case a PerformanceCounter) that is null to a method and set it to an instance of an object, the original null reference is not updated to point to the new object. This means that the PerformanceCounter will continue to be null.

The solution is to instantiate the PerformanceCounter before calling the method...

This solution, unfortunately, is not really relevant to the core topic of the question asked, but I didn't know that at the time of asking it.

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