valid - ¿Cómo obtener el uso de la CPU en C#?
summary example c# (9)
CMS tiene razón, pero también si usa el explorador de servidor en Visual Studio y juega con la pestaña del contador de rendimiento, entonces puede descubrir cómo obtener muchas métricas útiles.
Quiero obtener el uso general total de la CPU para una aplicación en C #. He encontrado muchas maneras de profundizar en las propiedades de los procesos, pero solo quiero el uso de la CPU de los procesos, y la CPU total como la que obtiene en el Administrador de Tareas.
¿Cómo puedo hacer eso?
Después de pasar un tiempo leyendo un par de hilos diferentes que parecían bastante complicados, se me ocurrió esto. Lo necesitaba para una máquina de 8 núcleos donde quería monitorear el servidor SQL. Para el siguiente código, pasé en "sqlservr" como appName.
private static void RunTest(string appName)
{
bool done = false;
PerformanceCounter total_cpu = new PerformanceCounter("Process", "% Processor Time", "_Total");
PerformanceCounter process_cpu = new PerformanceCounter("Process", "% Processor Time", appName);
while (!done)
{
float t = total_cpu.NextValue();
float p = process_cpu.NextValue();
Console.WriteLine(String.Format("_Total = {0} App = {1} {2}%/n", t, p, p / t * 100));
System.Threading.Thread.Sleep(1000);
}
}
Parece medir correctamente el% de CPU que utiliza SQL en mi servidor de 8 núcleos.
Está bien, lo tengo! ¡Gracias por tu ayuda!
Aquí está el código para hacerlo:
private void button1_Click(object sender, EventArgs e)
{
selectedServer = "JS000943";
listBox1.Items.Add(GetProcessorIdleTime(selectedServer).ToString());
}
private static int GetProcessorIdleTime(string selectedServer)
{
try
{
var searcher = new
ManagementObjectSearcher
(@"//"+ selectedServer +@"/root/CIMV2",
"SELECT * FROM Win32_PerfFormattedData_PerfOS_Processor WHERE Name=/"_Total/"");
ManagementObjectCollection collection = searcher.Get();
ManagementObject queryObj = collection.Cast<ManagementObject>().First();
return Convert.ToInt32(queryObj["PercentIdleTime"]);
}
catch (ManagementException e)
{
MessageBox.Show("An error occurred while querying for WMI data: " + e.Message);
}
return -1;
}
Esta clase sondea automáticamente el contador cada 1 segundos y también es seguro para subprocesos:
public class ProcessorUsage
{
const float sampleFrequencyMillis = 1000;
protected object syncLock = new object();
protected PerformanceCounter counter;
protected float lastSample;
protected DateTime lastSampleTime;
/// <summary>
///
/// </summary>
public ProcessorUsage()
{
this.counter = new PerformanceCounter("Processor", "% Processor Time", "_Total", true);
}
/// <summary>
///
/// </summary>
/// <returns></returns>
public float GetCurrentValue()
{
if ((DateTime.UtcNow - lastSampleTime).TotalMilliseconds > sampleFrequencyMillis)
{
lock (syncLock)
{
if ((DateTime.UtcNow - lastSampleTime).TotalMilliseconds > sampleFrequencyMillis)
{
lastSample = counter.NextValue();
lastSampleTime = DateTime.UtcNow;
}
}
}
return lastSample;
}
}
Esto parece funcionar para mí, un ejemplo de esperar hasta que el procesador alcance un cierto porcentaje
var cpuCounter = new PerformanceCounter("Processor", "% Processor Time", "_Total");
int usage = (int) cpuCounter.NextValue();
while (usage == 0 || usage > 80)
{
Thread.Sleep(250);
usage = (int)cpuCounter.NextValue();
}
No me gustó tener que agregar el puesto de 1 segundo a todas las soluciones de PerformanceCounter
. En cambio, elegí usar una solución WMI
. La razón por la que la espera / pérdida de 1 segundo existe es para permitir que la lectura sea precisa cuando se utiliza un PerformanceCounter
. Sin embargo, si llama a este método a menudo y actualiza esta información, le aconsejaría que no tenga que incurrir constantemente en ese retraso ... incluso si piensa en hacer un proceso asíncrono para obtenerlo.
Empecé con el fragmento de aquí Devolviendo el uso de CPU en WMI usando C # y agregué una explicación completa de la solución en la publicación de mi blog a continuación:
Puede usar WMI para obtener información de porcentaje de CPU. Incluso puede iniciar sesión en una computadora remota si tiene los permisos correctos. Mira http://www.csharphelp.com/archives2/archive334.html para tener una idea de lo que puedes lograr.
También puede ser útil la referencia de MSDN para el espacio de nombres Win32_Process .
Vea también un ejemplo de CodeProject Cómo: (Casi) Todo en WMI a través de C # .
Puede usar la clase PerformanceCounter desde System.Diagnostics .
Inicializa así:
PerformanceCounter cpuCounter;
PerformanceCounter ramCounter;
cpuCounter = new PerformanceCounter("Processor", "% Processor Time", "_Total");
ramCounter = new PerformanceCounter("Memory", "Available MBytes");
Consumir así:
public string getCurrentCpuUsage(){
return cpuCounter.NextValue()+"%";
}
public string getAvailableRAM(){
return ramCounter.NextValue()+"MB";
}
Un poco más de lo que se requería, pero utilizo el código del temporizador adicional para rastrear y alertar si el uso de la CPU es del 90% o más durante un período sostenido de 1 minuto o más.
public class Form1
{
int totalHits = 0;
public object getCPUCounter()
{
PerformanceCounter cpuCounter = new PerformanceCounter();
cpuCounter.CategoryName = "Processor";
cpuCounter.CounterName = "% Processor Time";
cpuCounter.InstanceName = "_Total";
// will always start at 0
dynamic firstValue = cpuCounter.NextValue();
System.Threading.Thread.Sleep(1000);
// now matches task manager reading
dynamic secondValue = cpuCounter.NextValue();
return secondValue;
}
private void Timer1_Tick(Object sender, EventArgs e)
{
int cpuPercent = getCPUCounter();
if (cpuPercent >= 90)
{
totalHits = totalHits + 1;
if (totalHits == 60)
{
Interaction.MsgBox("ALERT 90% usage for 1 minute");
totalHits = 0;
}
}
else
{
totalHits = 0;
}
Label1.Text = cpuPercent + " % CPU";
Label2.Text = getRAMCounter() + " RAM Free";
Label3.Text = totalHits + " seconds over 20% usage";
}
}