7

诀窍是我还需要能够在多核机器上做到这一点。我的 C# 教育有点破。我已经管理了以下代码。谁能帮我吗?Iv 尝试使用“_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);
4

1 回答 1

17

您只能每 100 毫秒读取一次性能计数器,否则 timesilce 将太小而无法获得准确的读数,如果您每 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时仅报告 0 或 100%的原因是您当前是否正在执行代码是一个布尔因素NextValue

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

从上次性能计数器读取到现在,从进程 X 执行代码的时间片百分比是多少?

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

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

对于该问题,您可以得到的唯一两个答案是“否”(0%)或“是”(100%)。

于 2011-12-11T09:20:56.490 回答