我需要调用单个进程的准确CPU使用率

Trick是我还需要能够在多核机器上完成它。 我在C#的教育有点破碎。 我已经管理了以下代码。 谁能帮我吗? 我尝试使用“_Total”标志,我尝试修改其他一些看起来像是试图检测核心数量的代码片段。 我被告知他们不包括HT,只支持物理非逻辑处理器。 我试图让它做到这两点。 显然他们是一种手动执行此操作的方法

("Process", "% Processor Time", "1" process.ProcessName)) ("Process", "% Processor Time", "2" process.ProcessName)) ("Process", "% Processor Time", "3" process.ProcessName)) 

但是我发现如果内核不存在则硬件不起作用。 我希望我能遇到更灵活的事情。 我一直在这个工作几天几小时,我要把头发拉出来。

 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(); } } } } } } } 

编辑::我对代码进行了以下更改,以修复我的建议和基本实际问题。

  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); 

您每100 ms只能读取性能计数器,或者时间太小而无法获得准确的读数,如果您每100ms读取一次以上,它将始终报告0或100%的使用率。 因为您调用NextValue()两次(一次为文件,一次为您的流),第二次读取将是自上一次读取之前的行以来的用法。

将您的代码更改为:

 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); } } 

可能存在导致您出现问题的其他问题,但是两次调用NextValue是第一个跳出来的问题。


说明:

当您请求NextValue太快时, NextValue仅报告0或100%的原因是, 如果您当前正在执行代码,则是布尔因子

那么性能计数器正在做的是提出这样的问题:

在性能计数器最后一次读取之前和现在,从进程X执行代码的时间百分比是多少?

性能计数器使用的那些时间片的大小是100ms,所以如果你低于100ms,你基本上要求

性能计数器记录的最后一个时间片是否包含进程X执行的代码?

你可以得到的唯一两个答案是“不”(0%)或“是”(100%)。