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

Sol*_*s17 7 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))
Run Code Online (Sandbox Code Playgroud)

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

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

                        }
                    }
                }

            }

        }

    }

}
Run Code Online (Sandbox Code Playgroud)

编辑::我对代码进行了以下更改,以便根据建议和基本的方法解决我的问题.

    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);
Run Code Online (Sandbox Code Playgroud)

Sco*_*ain 17

您只能每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);
    }
}
Run Code Online (Sandbox Code Playgroud)

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


说明:

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

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

在性能计数器最后一次读取和现在之间,有多少时间切片从进程X执行代码?

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

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

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

  • 看起来不错,很高兴我可以帮忙.我唯一能推荐的其他东西可能比"睡眠(100)"(110或许?)要高一点,以确保你超过100毫秒的要求.另外,如果您查看如何执行[Parallel.ForEach](http://msdn.microsoft.com/en-us/library/dd991486.aspx)并将写入文件放在localFinally中(您将需要为文件写入添加一点锁定,因为多个线程将尝试立即写入文件)您不需要等待按顺序枚举每个进程,您可以同时获取所有这些进程的快照. (2认同)