获取CPU和RAM使用率

时间:2015-10-28 09:34:10

标签: c# cpu-usage system.diagnostics

我需要在执行进程期间获取内存和CPU使用率(该进程有时可以运行超过30分钟)。与任务管理器的值相比,我能够获得可用RAM,但CPU使用率不正确。难道我做错了什么?这是我的代码:

class Program
{
    static List<float> AvailableCPU = new List<float>();
    static List<float> AvailableRAM = new List<float>();

    protected static PerformanceCounter cpuCounter;
    protected static PerformanceCounter ramCounter;
    static void Main(string[] args)
    {
        cpuCounter = new PerformanceCounter();
        cpuCounter.CategoryName = "Processor";
        cpuCounter.CounterName = "% Processor Time";
        cpuCounter.InstanceName = "_Total";

        ramCounter = new PerformanceCounter("Memory", "Available MBytes");

        try
        {
            System.Timers.Timer t = new System.Timers.Timer(1200);
            t.Elapsed += new ElapsedEventHandler(TimerElapsed);
            t.Start();
            Thread.Sleep(10000);
        }
        catch (Exception e)
        {
            Console.WriteLine("catched exception");
        }
        Console.ReadLine();

    }

    public static void TimerElapsed(object source, ElapsedEventArgs e)
    {
        float cpu = cpuCounter.NextValue();
        float ram = ramCounter.NextValue();
        Console.WriteLine(string.Format("CPU Value: {0}, ram value: {1}", cpu, ram));
        AvailableCPU.Add(cpu);
        AvailableRAM.Add(ram);
    }

}

但是当我运行程序时,这是打印到控制台的内容,与任务管理器的值进行比较: cpu usage

我做错了什么?

2 个答案:

答案 0 :(得分:9)

你的价值观没有错。

您看到与任务管理器返回的差异的原因是“CPU使用率”值是针对给定间隔计算的,即两次Protected Sub gvList_RowDataBound(ByVal sender As Object, ByVal e As System.Web.UI.WebControls.GridViewRowEventArgs) Handles gvList.RowDataBound Dim j As Integer = 0 If e.Row.RowType == DataControlRowType.DataRow Then // Find the button Dim totalButton As LinkButton = DirectCast(e.Row.FindControl("lnkEdit"), LinkButton) arrTotalPage(j) += Convert.ToDecimal(totalButton.Text) End If End Sub 次调用之间的值。如果任务管理器“不调用它自己的NextValue”(如果我们简化它的工作原理),你将不会返回相同的结果。

想象一下以下场景:

NextValue()
  • 如果您检查时间1和时间3之间的值,您将返回基于“50%和2%”的内容。
  • 如果任务管理器检查时间2和时间4之间的值,它将返回不同的值,即基于“70%和100%”的值。

您可以尝试生成自己应用程序的多个进程,还应该看到不同的结果。

答案 1 :(得分:8)

以下是我发现的内容:我为每个核心创建了一个包含PerformanceCounter个对象的列表,我添加百分比并将结果除以数据核心数量:

    class Program
    {
        static List<float> AvailableCPU = new List<float>();
        static List<float> AvailableRAM = new List<float>();

        protected static PerformanceCounter cpuCounter;
        protected static PerformanceCounter ramCounter;
        static List<PerformanceCounter> cpuCounters = new List<PerformanceCounter>();
        static int cores = 0;
        static void Main(string[] args)
        {
            cpuCounter = new PerformanceCounter();
            cpuCounter.CategoryName = "Processor";
            cpuCounter.CounterName = "% Processor Time";
            cpuCounter.InstanceName = "_Total";

            foreach (var item in new System.Management.ManagementObjectSearcher("Select * from Win32_Processor").Get())
            {
                cores = cores + int.Parse(item["NumberOfCores"].ToString());
            }

            ramCounter = new PerformanceCounter("Memory", "Available MBytes");

            int procCount = System.Environment.ProcessorCount;
            for(int i = 0; i < procCount; i++)
            {
                System.Diagnostics.PerformanceCounter pc = new System.Diagnostics.PerformanceCounter("Processor", "% Processor Time", i.ToString());
                cpuCounters.Add(pc);
            }

            Thread c = new Thread(ConsumeCPU);
            c.IsBackground = true;
            c.Start();

            try
            {
                System.Timers.Timer t = new System.Timers.Timer(1200);
                t.Elapsed += new ElapsedEventHandler(TimerElapsed);
                t.Start();
                Thread.Sleep(10000);
            }
            catch (Exception e)
            {
                Console.WriteLine("catched exception");
            }
            Console.ReadLine();

        }

        public static void ConsumeCPU()
        {
            int percentage = 60;
            if (percentage < 0 || percentage > 100)
                throw new ArgumentException("percentage");
            Stopwatch watch = new Stopwatch();
            watch.Start();
            while (true)
            {
                // Make the loop go on for "percentage" milliseconds then sleep the 
                // remaining percentage milliseconds. So 40% utilization means work 40ms and sleep 60ms
                if (watch.ElapsedMilliseconds > percentage)
                {
                    Thread.Sleep(100 - percentage);
                    watch.Reset();
                    watch.Start();
                }
            }
        }

        public static void TimerElapsed(object source, ElapsedEventArgs e)
        {
            float cpu = cpuCounter.NextValue();
            float sum = 0;
            foreach(PerformanceCounter c in cpuCounters)
            {
                sum = sum + c.NextValue();
            }
            sum = sum / (cores);
            float ram = ramCounter.NextValue();
            Console.WriteLine(string.Format("CPU Value 1: {0}, cpu value 2: {1} ,ram value: {2}", sum, cpu, ram));
            AvailableCPU.Add(sum);
            AvailableRAM.Add(ram);
        }

    }

以下是结果的截图(如您所见,第一种方法更精确):

enter image description here