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

标签 c# console multicore cpu-speed

诀窍是我还需要能够在多核机器上完成它。我在 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 毫秒读取一次性能计数器,否则时间间隔太小而无法获得准确的读数,如果您每 100 毫秒读取一次以上,它将始终报告 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% 的原因是您当前是否正在执行代码是一个事实 bool 因子

所以性能计数器正在做的是问这个问题:

Between the last time the performance counter took a reading and right now, what % of time slices had code executing from the process X?

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

Did the last time slice that was recorded by the performance counter have code from the process X executing?

对于这个问题,您只能得到两个答案:“否”(0%) 或"is"(100%)。

关于c# - 我需要调用单个进程的准确CPU使用率,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8462331/

相关文章:

c# - 对于 Foundation/ZURB,随机 "data-section-content"是做什么用的?

c# - 命名空间/引用错误

java - 在 IBM RAD WebSphere 中,哪个文件描述了管理控制的 WebSphere 变量?

Java进程构建器获取构建命令

R 多核 mcfork() : Unable to fork: Cannot allocate memory

c# - 将 pdf 文件发送到打印机 - 打印 pdf

通过 VS 2005 将 excel 电子表格上传到 SQL 数据库时的 C# 用户界面

java - 在 Java 的 for 循环中使用 Println 函数?

macos - 禁用内核如何影响正在运行的进程?