这就是我在 form1 中所做的:
void PopulateApplications()
{
DoubleBufferedd(dataGridView1, true);
int rcount = dataGridView1.Rows.Count;
int rcurIndex = 0;
foreach (Process p in Process.GetProcesses())
{
try
{
if (File.Exists(p.MainModule.FileName))
{
memoryUsage = Core.getallmemoryusage(p.ProcessName);
Core.getcpu(p.ProcessName);
cpuusage = Core.processes;
var icon = Icon.ExtractAssociatedIcon(p.MainModule.FileName);
Image ima = icon.ToBitmap();
ima = resizeImage(ima, new Size(25, 25));
ima = (Image)(new Bitmap(ima, new Size(25, 25)));
String status = p.Responding ? "Running" : "Not Responding";
if (rcurIndex < rcount - 1)
{
var currentRow = dataGridView1.Rows[rcurIndex];
currentRow.Cells[0].Value = ima;
currentRow.Cells[1].Value = p.ProcessName;
currentRow.Cells[2].Value = cpuusage;
currentRow.Cells[3].Value = memoryUsage;
currentRow.Cells[4].Value = status;
}
else
{
dataGridView1.Rows.Add(ima, p.ProcessName,cpuusage,memoryUsage, status);//false, ima, p.ProcessName, status);
}
rcurIndex++;
}
}
catch ( Exception e)
{
string t = "error";
}
}
if (rcurIndex < rcount - 1)
{
for (int i = rcurIndex; i < rcount - 1; i++)
{
dataGridView1.Rows.RemoveAt(rcurIndex);
}
}
}
现在是 form1 PopulateApplications
中的方法,我每 5 秒从计时器滴答事件中调用它。
然后我每次循环处理这些进程并获取内存使用情况和 CPU 使用情况。
这是Core
类中内存和CPU的方法。
用内存法是没有问题的。工作又好又快。
public static string getallmemoryusage(string processName)
{
var counter = new PerformanceCounter("Process", "Working Set - Private", processName);
privateMemeory = (counter.NextValue() / 1024 / 1024).ToString();
//string.Format("Private memory: {0}k", counter.NextValue() / 1024 / 1024);
return privateMemeory;
}
问题出在 getcpu
方法上。我需要让它每 1000 毫秒休眠几次以获得 CPU 使用率。如果我在这个方法上使用断点,我会得到最后的值。问题是当我每 5 秒调用 form1 中的方法时,它也会每 5 秒调用并执行此 getcpu
并且那些线程 sleep 使其工作非常慢。如果我将线程休眠设置为 10 毫秒,它会更快,但大多数进程的使用率会达到 0% 或 100%。
public static string getcpu(string name)
{
var cpuload = new PerformanceCounter("Processor", "% Processor Time", "_Total");
processes = Convert.ToInt32(cpuload.NextValue()) + "%";
System.Threading.Thread.Sleep(1000);
processes = cpuload.NextValue() + "%";
System.Threading.Thread.Sleep(1000);
processes = cpuload.NextValue() + "%";
System.Threading.Thread.Sleep(1000);
processes = cpuload.NextValue() + "%";
System.Threading.Thread.Sleep(1000);
processes = cpuload.NextValue() + "%";
System.Threading.Thread.Sleep(1000);
return processes;
}
最佳答案
当测量 % Processor Time
时,Thread.Sleep(1000)
是必需的,因为 .NextValue()
调用决定了时间,自上次调用 .NextValue()
以来使用了处理器。有关此计算的更多信息,请查看 https://learn.microsoft.com/en-us/archive/blogs/bclteam/how-to-read-performance-counters-ryan-byington .
一些建议:
- 由于您传递的是进程名称,我假设您想要测量单个进程的处理器时间。但是由于您没有在您的方法中使用该参数,因此您测量的是总体平均系统处理器时间。
所以如果你想衡量一个进程的性能,你可以使用类似的东西:
public static double GetCpuUsage(Process process)
{
PerformanceCounter cpuCounter = new PerformanceCounter();
cpuCounter.CategoryName = "Process";
cpuCounter.InstanceName = process.ProcessName;
cpuCounter.CounterName = "% Processor Time";
// The first call will always return 0
cpuCounter.NextValue();
// That's why we need to sleep 1 second
Thread.Sleep(1000);
// The second call determines, the % of time that the monitored process uses on
// % User time for a single processor.
// So the limit is 100% * the number of processors you have.
double processorUsagePercent = cpuCounter.NextValue();
// Hence we need to divide by the number of processors to get the average CPU usage of one process during the time measured
return processorUsagePercent / Environment.ProcessorCount;
}
请注意计数器类别的"Processor"
和"Process"
之间的区别。
为什么连续多次调用
.NextValue()
然后只返回最后一个值?这使您的方法如此缓慢。上面示例中显示的两个计算就足够了。当您想要监视多个进程时,您不必在每次调用
.NextValue()
之间等待一秒钟。您只需确保自上次在特定计数器上调用.NextValue()
以来至少过去了一秒钟。因此,对于多个进程,您可以使用这样的方法:public static Dictionary
GetCpuUsages(Process[] 进程) { //每个进程需要一个性能计数器 PerformanceCounter[] counters = new PerformanceCounter[processes.Length]; // Instantiate a new counter per process for(int i = 0; i < processes.Length; i++) { PerformanceCounter processorTimeCounter = new PerformanceCounter( "Process", "% Processor Time", processes[i].ProcessName); // Call NextValue once to have a reference value processorTimeCounter.NextValue(); // Add it to the array counters[i] = processorTimeCounter; } // Sleep one second to have accurate measurement Thread.Sleep(1000); // Here we store the processes along with their measurement in a dictionary Dictionary<Process, double> cpuUsageDictionary = new Dictionary<Process, double>(); for (int i = 0; i < counters.Length; i++) { // Determine CPU usage and divide by the number of cores double cpuUsage = counters[i].NextValue() / Environment.ProcessorCount; // And now we add one key/value pair per process along with its cpu time measurement cpuUsageDictionary.Add(processes[i], cpuUsage); } return cpuUsageDictionary;
关于c# - 为什么我的 CPU 使用率一直是 0%?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24122604/