Como medir o uso da CPU utilizando Performance Counters
Na última semana no trabalho, dois desenvolvedores estavam procurando uma forma de recuperar a porcentagem de uso da CPU utilizando .NET. Eles encontraram uma solução utilizando Win32_Processor de WMI e classes do namesapce System.Management, escrevendo algo mais ou menos assim:
ObjectQuery query = new ObjectQuery("SELECT * FROM Win32_Processor");
ManagementObjectSearcher searcher = new ManagementObjectSearcher(query);
int load = 0;
int cpus = 0;
foreach (ManagementObject mo in searcher.Get())
{
load += Convert.ToInt32(mo["LoadPercentage"]);
numCpus++;
}
decimal cpuUsage = load / cpus;
Uma maneira mais fácil de fazer isso, e que atende ao propósito de medir recursos utilizados da máquina, é utilizar Performance Counters. Classes como PerformanceCounter e PerformanceCounterCategory, que são encontradas no namespace System.Diagnostics, lhe dão acesso não somente a informações do uso do processador, mas também informações sobre cachê de sistema, disco físico, memória, threads, entre outros.
O exemplo abaixo mostra como criar uma instância da classe PerformanceCounter para recuperar a porcentagem do uso da CPU naquele instante:
PerformanceCounter cpuCounter = new PerformanceCounter
{
CategoryName = "Processor",
CounterName = "% Processor Time",
InstanceName = "_Total"
};
float cpuUsage = cpuCounter.NextValue();
Note que na propriedade CategoryName é informado “Processor”, a categoria referente ao processador da máquina, e na propriedade CounterName, o contador que se refere à porcentagem do tempo de processamento. Em algumas categorias de Performance Counter é necessário especificar o nome da instância do contador, através da propriedade InstanceName, como é o caso da categoria “Processor” do exemplo acima, onde está sendo utilizado a instância “_Total”. Na minha máquina, para a categoria “Processor”, também estão disponíveis as instâncias “0″ e “1″, que se referem aos dois núcleos do meu AMD Athlon™ 64 X2 Dual Core Processor 6000+.
Na categoria “Memory” não é necessário especificar o nome da instância. Veja abaixo o exemplo de como obter a quantidade de memória disponível:
PerformanceCounter ramCounter = new PerformanceCounter
{
CategoryName = "Memory",
CounterName = "Available MBytes"
};
float availableRam = ramCounter.NextValue();
Para recuperar todas as categorias disponíveis para medição, use o método GetCategories da classe PerformanceCounterCategory:
PerformanceCounterCategory[] categories; categories = PerformanceCounterCategory.GetCategories();
A partir de uma categoria, você pode recuperar todas os nomes de contadores. Por exemplo, o código abaixo:
var category = new PerformanceCounterCategory("System");
foreach (PerformanceCounter counter in category.GetCounters())
{
Console.WriteLine(counter.CounterName);
}
Gera a seguinte saída:
File Read Operations/sec File Write Operations/sec File Control Operations/sec File Read Bytes/sec File Write Bytes/sec File Control Bytes/sec Context Switches/sec System Calls/sec File Data Operations/sec System Up Time Processor Queue Length Processes Threads Alignment Fixups/sec Exception Dispatches/sec Floating Emulations/sec % Registry Quota In Use
Eu fiz duas aplicações console de exemplo utilizando Performance Counters:
- Uma exibe a porcentagem de uso da CPU e a quantidade de MB de memória disponíveis, atualizando as informações a cada um segundo;
- A outra lista todos os nomes de instâncias e contadores de algumas categorias.
Você pode baixar essas duas aplicações aqui.


Comentários