简体   繁体   中英

'System.InvalidOperationException' occurred in System.dll

I'm trying to write simple resource monitor inside a console application. Monitor should show free RAM memory, used RAM memory, total RAM memory, CPU load, etc.

When I try to run the program I get this exception:

"An unhandled exception of type 'System.InvalidOperationException' occurred in System.dll

Additional information: Instance '0,2' does not exist in the specified Category."

This is complete code:

using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading;
using System.Threading.Tasks;


namespace MachineUsage
{
    class Program
    {

        static Double MemoryRAM;
        static PerformanceCounter ramCounter;
        static Int32 CoreCount;

        [DllImport("user32.dll", SetLastError = true)]
        [return: MarshalAs(UnmanagedType.Bool)]
        private static extern bool SetWindowPos
            (
            IntPtr hWnd,
            IntPtr hWndInsertAfter,
            int x,
            int y,
            int cx,
            int cy,
            int uFlags
            );

        private const int HWND_TOPMOST = -1;
        private const int SWP_NOMOVE = 0x0002;
        private const int SWP_NOSIZE = 0x0001;

        static PerformanceCounter cpuUsage;

        static void Main(string[] args)
        {
            //Thread CPUthread = new Thread(ResourcesUsage);
            //CPUthread.Start();

            MemoryRAM = getRAM();
            CoreCount = getCoreCount();
            IntPtr hWnd = Process.GetCurrentProcess().MainWindowHandle;

            SetWindowPos
                (
                hWnd,
                new IntPtr(HWND_TOPMOST),
                0, 0, 0, 0,
                SWP_NOMOVE | SWP_NOSIZE
                );

            var pc = new PerformanceCounter("Processor", "% Processor Time", "_Total");
            var cat = new PerformanceCounterCategory("Processor Information");

            var instances = cat.GetInstanceNames();
            var cs = new Dictionary<string, CounterSample>();

            Console.WindowHeight = 6;
            Console.WindowWidth = 32;
            Console.Title = "Resources monitor";

            foreach (var s in instances)
            {
                pc.InstanceName = s;
                cs.Add(s, pc.NextSample());
            }

            while (true)
            {
                var s = instances[0];
                pc.InstanceName = s;
                Console.WriteLine("Core count: " + CoreCount + " cores");
                Console.WriteLine("CPU load: " + String.Format("{0:F2}", Calculate(cs[s], pc.NextSample())) + " %");
                Console.WriteLine("Avilable memory: " + getAvailableRAM() + " MB");
                Console.WriteLine("Not avilable memory: " + getNotAvailableRAM() + " MB");
                Console.WriteLine("All memory: " + MemoryRAM + " MB");
                cs[s] = pc.NextSample();
                Thread.Sleep(1000);
                Console.Clear();
            }
        }

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

            return CoreCount;
        }

        public static Double Calculate(CounterSample oldSample, CounterSample newSample)
        {
            double difference = newSample.RawValue - oldSample.RawValue;
            double timeInterval = newSample.TimeStamp100nSec - oldSample.TimeStamp100nSec;
            if (timeInterval != 0 )
            {
                return 100 * (1 - (difference / timeInterval));
            }
            else
            {
                return 0;
            }
        }

        public static Double getRAM()
        {
            UInt64 SizeinKB = Convert.ToUInt64(new Microsoft.VisualBasic.Devices.ComputerInfo().TotalPhysicalMemory);
            UInt64 SizeinMB = SizeinKB / 1024;
            UInt64 SizeinGB = SizeinMB / 1024;
            Double result = Convert.ToInt32(SizeinGB);
            return result;
        }

        public static Double getAvailableRAM()
        {
            ramCounter = new PerformanceCounter("Memory", "Available MBytes");
            Double result = System.Convert.ToDouble(ramCounter.NextValue());
            return result;
        }

        public static Double getNotAvailableRAM()
        {
            Double result = MemoryRAM - getAvailableRAM();
            return result;
        }

        //public static void ResourcesUsage()
        //{
        //    while(true)
        //    {
        //        cpuUsage = new PerformanceCounter("Processor", "% Processor Time", "_Total");

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

        //        Console.Clear();
        //        Console.WriteLine("CPU: "+ cpuUsage.NextValue() + " %");
        //        Console.WriteLine("RAM: " + ramCounter.NextValue() + " MB");
        //        Thread.Sleep(1000);


        //    }
        //}
    }


}

My PerformanceCounter (pc) vas defined wrong.

This is the fix:

var pc = new PerformanceCounter("Processor Information", "% Processor Time");

I found my answer here: How can I get CPU load per core in C#?

At first I didn't even check PerformanceCounter then I copy-pasted code and it worked. Thanks anyways guys.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM