c# - soporta - Necesito llamar el uso preciso de la CPU de un solo proceso
optimizacion de consultas sql (1)
El truco es que también necesito poder hacerlo en máquinas multi core. Mi educación en C # está un poco rota. Logré el siguiente código. ¿Puede alguien ayudarme? Iv intentó usar el indicador "_Total" y he intentado modificar algunos otros fragmentos de código que parecían tratar de detectar la cantidad de núcleos. Sin embargo, me dijeron que no incluían HT y solo admitían procesadores físicos no lógicos. Intentaba hacer que hiciera ambas cosas. Al parecer, es una forma de hacer esto manualmente usando
("Process", "% Processor Time", "1" process.ProcessName))
("Process", "% Processor Time", "2" process.ProcessName))
("Process", "% Processor Time", "3" process.ProcessName))
etc. Pero descubrí el hardware que no funciona si los núcleos no existen. Esperaba poder encontrar algo más flexible. He estado trabajando en esto durante días, horas y horas a la vez y voy a sacar mi pelo.
using System;
using System.Collections.Generic;
using System.Text;
using System.Diagnostics;
using System.Threading;
using System.Collections;
using System.IO;
namespace Program_CPU_Monitor
{
class Program
{
static void Main(string[] args)
{
StreamWriter log;
log = File.AppendText("c://CPUMON.txt");
log.WriteLine("");
log.WriteLine("**Started logging Program CPU Monitor (2.6.0.63)**");
log.Close();
Console.Title = "Program CPU Monitor 2.6.0.63";
Console.WriteLine("Monitoring Program CPU & Memory usage...(1-min intervals)");
Console.WriteLine("Monitoring will start when Program is detected as running.");
Console.WriteLine("Please type in program name without the ''.EXE'', For example ''TESV'' or ''calc''.");
Console.WriteLine("The program name is case sensative. Without the proper case it will not work.");
Console.WriteLine("This program will leave a log of the display called ''CPUMON.txt'' on drive C:/.");
Console.WriteLine("Please type program name...");
Console.WriteLine("");
string procName = Console.ReadLine();
while (true)
{
Process[] runningNow = Process.GetProcesses();
foreach (Process process in runningNow)
{
using (PerformanceCounter pcProcess = new PerformanceCounter("Process", "% Processor Time", process.ProcessName))
using (PerformanceCounter memProcess = new PerformanceCounter("Memory", "Available MBytes"))
{
if (process.ProcessName == procName)
{
pcProcess.NextValue();
Thread.Sleep(60000);
StreamWriter OurStream;
OurStream = File.AppendText("c://CPUMON.txt");
Console.WriteLine("");
OurStream.WriteLine("");
Console.ForegroundColor = ConsoleColor.Red;
Console.WriteLine("Process: ''{0}'' CPU Usage: {1}%", process.ProcessName, pcProcess.NextValue());
OurStream.WriteLine("Process: ''{0}'' CPU Usage: {1}%", process.ProcessName, pcProcess.NextValue());
Console.ForegroundColor = ConsoleColor.Green;
Console.WriteLine("Process: ''{0}'' RAM Free: {1}MB", process.ProcessName, memProcess.NextValue());
OurStream.WriteLine("Process: ''{0}'' RAM Free: {1}MB", process.ProcessName, memProcess.NextValue());
Console.ForegroundColor = ConsoleColor.Cyan;
Console.WriteLine(string.Format("Recorded: ''{0}'' at {1}", procName, DateTime.Now.ToString()));
OurStream.WriteLine(string.Format("Recorded: ''{0}'' at {1}", procName, DateTime.Now.ToString()));
OurStream.Close();
}
}
}
}
}
}
}
EDIT :: Realicé los siguientes cambios en el código para solucionar mis problemas según el consejo y el entorno fidedigno.
foreach (Process process in runningNow)
{
using (PerformanceCounter cpuUsage = new PerformanceCounter("Process", "% Processor Time", "_Total"))
using (PerformanceCounter pcProcess = new PerformanceCounter("Process", "% Processor Time", process.ProcessName))
using (PerformanceCounter memProcess = new PerformanceCounter("Memory", "Available MBytes"))
{
if (process.ProcessName == procName)
{
StreamWriter OurStream;
OurStream = File.AppendText("c://CPUMON.txt");
Console.WriteLine("");
OurStream.WriteLine("");
// Prime the Performance Counters
pcProcess.NextValue();
cpuUsage.NextValue();
Thread.Sleep(100);
isprimed = true;
double cpuUse = Math.Round(pcProcess.NextValue() / cpuUsage.NextValue() * 100, 2);
// Check for Not-A-Number (Division by Zero)
if (Double.IsNaN(cpuUse))
cpuUse = 0;
//Get CPU Usage
Console.ForegroundColor = ConsoleColor.Red;
Console.WriteLine("Process: `{0}'' CPU Usage: {1}%", process.ProcessName, Convert.ToInt32(cpuUse));
OurStream.WriteLine("Process: `{0}'' CPU Usage: {1}%", process.ProcessName, Convert.ToInt32(cpuUse));
// Get Process Memory Usage
Console.ForegroundColor = ConsoleColor.Green;
double memUseage = process.PrivateMemorySize64 / 1048576;
Console.WriteLine("Process: `{0}'' Memory Usage: {1}MB", process.ProcessName, memUseage);
OurStream.WriteLine("Process: `{0}'' Memory Usage: {1}MB", process.ProcessName, memUseage);
// Get Total RAM free
Console.ForegroundColor = ConsoleColor.Cyan;
float mem = memProcess.NextValue();
Console.WriteLine("During: `{0}'' RAM Free: {1}MB", process.ProcessName, mem);
OurStream.WriteLine("During: `{0}'' RAM Free: {1}MB", process.ProcessName, mem);
//Record and close stream
Console.ForegroundColor = ConsoleColor.Yellow;
System.DateTime newDate = System.DateTime.Now;
Console.WriteLine("Recorded: {0}", newDate);
OurStream.WriteLine("Recorded: {0}", newDate);
OurStream.Close();
Thread.Sleep(59900);
Solo puede leer los contadores de rendimiento cada 100 ms o el intervalo de tiempo será demasiado pequeño para que obtenga una lectura precisa; si lee más de una vez cada 100 ms, siempre informará 0 o 100% de uso. Debido a que llama a NextValue()
dos veces (una vez para el archivo, una vez para su transmisión) la segunda lectura será el uso desde la lectura previa de la línea anterior.
Cambia tu código a esto:
foreach (Process process in runningNow.Where(x => x.ProcessName == procName)
{
using (PerformanceCounter pcProcess = new PerformanceCounter("Process", "% Processor Time", process.ProcessName))
using (PerformanceCounter memProcess = new PerformanceCounter("Memory", "Available MBytes"))
{
pcProcess.NextValue();
Thread.Sleep(60000);
StreamWriter OurStream;
OurStream = File.AppendText("c://CPUMON.txt");
Console.WriteLine("");
OurStream.WriteLine("");
Console.ForegroundColor = ConsoleColor.Red;
float cpuUseage = pcProcess.NextValue();
Console.WriteLine("Process: ''{0}'' CPU Usage: {1}%", process.ProcessName, cpuUseage);
OurStream.WriteLine("Process: ''{0}'' CPU Usage: {1}%", process.ProcessName, cpuUseage);
Console.ForegroundColor = ConsoleColor.Green;
float memUseage = memProcess.NextValue();
Console.WriteLine("Process: ''{0}'' RAM Free: {1}MB", process.ProcessName, memUseage);
OurStream.WriteLine("Process: ''{0}'' RAM Free: {1}MB", process.ProcessName, memUseage);
}
}
Puede haber otros problemas que le causen problemas, pero llamar a NextValue dos veces es el primero que saltó sobre mí.
Explicación:
La razón detrás de NextValue
solo informando 0 o 100% cuando solicita NextValue
demasiado rápido es el hecho de que si está ejecutando código actualmente o no, es un factor booleano .
Entonces, ¿qué está haciendo el contador de rendimiento? Es hacer la pregunta:
Entre la última vez que el contador de rendimiento tomó una lectura y en este momento, ¿qué porcentaje de cortes de tiempo tenía el código ejecutándose desde el proceso X?
El tamaño de las franjas horarias con las que funciona el contador de rendimiento es de 100 ms, por lo que si pasas por debajo de 100 ms, básicamente estás preguntando
¿El último segmento de tiempo que fue registrado por el contador de rendimiento tiene código del proceso X ejecutándose?
y las únicas dos respuestas que puede obtener son "No" (0%) o "Sí" (100%).