Processor Usage

G

Guest

I have a logging application that records various performance metrics into a database every 5 minutes, and to this I'd like to add a performace counter that shows the processor usage in a manner akin to what you see in the Performance tab of the Task Manager -- whatever that value is when the timer fires is what I want to record

I'm using System.Diagnostics.PerformanceCounter with the "% Processor Time" counter, but I'm having a problem. The counter grabs the instantaneous usage, giving me something like: 0, 0, 0, 0, 0, 0, 100, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 100, etc. If I let the program run for long enough, the 100s turn to 26.738 or 33.242 -- following closely the values shown in the Task Manager. I assume that in the Task Manager or in perfmon.msc it takes a specified (seemingly large) number of samples per second and averages them to get the final value, and I've thought about doing that, but even simply spitting out the value of the counter continuously jumped processor usage up quite high. For me to sit in a loop taking samples and then average them when a 1-second timer (or 5-minute) timer fires seems like it'd be a huge CPU gobbler, which I can't have

Is there a way I can get the values that are showing when I load that counter into Performance Monitor, or does anyone have any other ideas about how to do this

Thanks
Jeff
 
W

Willy Denoyette [MVP]

Can't answer your question without seeing some of your code, but following
is a sample, using System.Management classes, illustrating how to read high
performance counters from WMI .
Note: on the latest OS'ses (XP and up), perfmon uses WMI to read coocked
performance counters.
The algorithm used here might get you some idea's.

using System;
using System.Diagnostics;
using System.Threading;
using System.Timers;
using System.Management;
class Procperf
{
System.Timers.Timer aTimer;
ManagementObject pRawProc;
decimal prpct;
ulong prevCountBase = 0;
ulong newCountBase = 0;
ulong prevCountTime = 0;
ulong newCountTime = 0;

public Procperf(string instance)
{
aTimer = new System.Timers.Timer();
aTimer.Elapsed += new ElapsedEventHandler(this.OnTimer);
// set interval to 3 sec.
aTimer.Interval = 3000;
aTimer.Enabled = true;
aTimer.AutoReset = false;
// Using Raw Processor performance counters
pRawProc = new
ManagementObject("Win32_PerfRawData_PerfOS_Processor.Name='" + instance +
"'");
Console.Write("Processor %\n----------------- ");
}
public void OnTimer(Object source, ElapsedEventArgs e)
{
// PercentProcessorTime use timer algorithm PERF_100NSEC_TIMER_INV
// 100*(1-(X1-X0)/(Y1-Y0))
pRawProc.Get();
newCountTime = (ulong)pRawProc.Properties["PercentProcessorTime"].Value;
newCountBase = (ulong)pRawProc.Properties["Timestamp_Sys100Ns"].Value;
decimal pptd = Convert.ToDecimal(newCountTime);
decimal pptde = Convert.ToDecimal(prevCountTime);
decimal ppbd = Convert.ToDecimal(newCountBase);
decimal ppbde = Convert.ToDecimal(prevCountBase);
prpct = 100 *(1 - (pptde - pptd) / ( ppbde - ppbd)) ;
Console.WriteLine("{0:f3}",prpct);
prevCountBase = newCountBase;
prevCountTime = newCountTime;
System.Timers.Timer theTimer = (System.Timers.Timer)source;
theTimer.Enabled = true;
}
public void Close()
{
pRawProc.Dispose();
}
}
public class PCReadWMI {
public static void Main(string[] args){
string instance = "_total";

Procperf pp = new Procperf(instance);
Console.WriteLine("Press \'q\' to quit the sample");
while ( Console.Read()!='q' ) {
Thread.Sleep(2000);
}
pp.Close();
}
}

Willy.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top