C # Performance Map Counter across Map

I need to calculate CPU and RAM usage for the whole system, as well as for a specific process. I have never done this in C #. So I was able to come up with the following code (which I took mainly from samples on this website):

try
{
    Process proc = Process.GetCurrentProcess();
    string strProcName = proc.ProcessName;
    Console.WriteLine("Process: " + strProcName);

    using (PerformanceCounter total_cpu = new PerformanceCounter("Process", "% Processor Time", "_Total", true))
    {
        using (PerformanceCounter process_cpu = new PerformanceCounter("Process", "% Processor Time", strProcName, true))
        {
            for (; ; )
            {
                Console.CursorTop = 1;
                Console.CursorLeft = 0;

                float t = total_cpu.NextValue() / Environment.ProcessorCount;
                float p = process_cpu.NextValue() / Environment.ProcessorCount;
                Console.WriteLine(String.Format("Total CPU (%) = {0}\t\t\nApp CPU (%) = {1}\t\t\nApp RAM (KB) = {2}",
                    t, p, Process.GetCurrentProcess().WorkingSet64 / (1024)
                    ));

                System.Threading.Thread.Sleep(100);
            }
        }
    }
}
catch(Exception ex)
{
    Console.WriteLine("Exception: " + ex);
}

But what it gives me is the data "all over the map." Take a look:

enter image description here

enter image description here

enter image description here

So can someone answer these questions:

  • It seems that starting up such a performance counter is a rather expensive operation in itself - it increases processor load by about 5%. I made a ton of CPU counters with C ++, and they take almost no CPU time to start.

  • , , 2- ! 2 . ? , , :)

  • , , , . - , ?

  • , PerformanceCounter, : % Processor Time, _Total ..? , ? , ?

  • . , . ?

+5
2

, API:

[DllImport("kernel32.dll")]
[return: MarshalAs(UnmanagedType.Bool)]
static extern bool GetProcessTimes(IntPtr hProcess, out System.Runtime.InteropServices.ComTypes.FILETIME
    lpCreationTime, out System.Runtime.InteropServices.ComTypes.FILETIME lpExitTime, out System.Runtime.InteropServices.ComTypes.FILETIME lpKernelTime,
    out System.Runtime.InteropServices.ComTypes.FILETIME lpUserTime);

[DllImport("kernel32.dll")]
[return: MarshalAs(UnmanagedType.U4)]
static extern UInt32 GetTickCount();

static bool gbSetOldData = false;
static UInt32 gmsOldTickCount = 0;
static ulong gnsOldKernelTime = 0;
static ulong gnsOldUserTime = 0;

public static double getCPUUsageForProcess(int nProcID = 0)
{
    //Get CPU usage for the process in with ID in 'nProcID'
    //'nProcID' = process ID, or 0 for the current process
    //RETURN:
    //      = CPU usage: [0.0 - 1.0]
    //      = Negative if error
    double fCPUUsage = -1.0;
    try
    {
        IntPtr hProcess = nProcID != 0 ? Process.GetProcessById(nProcID).Handle : Process.GetCurrentProcess().Handle;

        System.Runtime.InteropServices.ComTypes.FILETIME ftCreated, ftExit, ftKernel, ftUser;
        if (GetProcessTimes(hProcess, out ftCreated, out ftExit, out ftKernel, out ftUser))
        {
            UInt32 dwmsNewTickCount = GetTickCount();

            ulong nsNewKernelTime = (ulong)ftKernel.dwHighDateTime;
            nsNewKernelTime <<= 32;
            nsNewKernelTime |= (ulong)(uint)ftKernel.dwLowDateTime;

            ulong nsNewUserTime = (ulong)ftUser.dwHighDateTime;
            nsNewUserTime <<= 32;
            nsNewUserTime |= (ulong)(uint)ftUser.dwLowDateTime;

            if (gbSetOldData)
            {
                //Adjust from 100-nanosecond intervals to milliseconds
                //100-nanosecond intervals = 100 * 10^-9 = 10^-7
                //1ms = 10^-3
                fCPUUsage = (double)((nsNewKernelTime - gnsOldKernelTime) + (nsNewUserTime - gnsOldUserTime)) /
                    (double)((dwmsNewTickCount - gmsOldTickCount) * 10000);

                //Account for multiprocessor architecture
                fCPUUsage /= Environment.ProcessorCount;

                //In case timer API report is inaccurate
                if (fCPUUsage > 1.0)
                    fCPUUsage = 1.0;
            }
            else
            {
                //For the first run, assume no CPU usage
                fCPUUsage = 0.0;
            }

            //Remember data
            gnsOldKernelTime = nsNewKernelTime;
            gnsOldUserTime = nsNewUserTime;
            gmsOldTickCount = dwmsNewTickCount;
            gbSetOldData = true;
        }
    }
    catch
    {
        //Failed
        fCPUUsage = -1.0;
    }

    return fCPUUsage;
}

:

int nDummy = 1;

for (; ; )
{
    double fCPU = getCPUUsageForProcess();

    Console.CursorTop = 1;
    Console.CursorLeft = 0;

    int nCpu = (int)(fCPU * 100);
    Console.WriteLine("CPU%: {0}\t\t", nCpu);

    //Time filler
    long j = 0;
    for (; j < 1000000; j++)
    {
        nDummy += (int)Math.Cos(1 / (j + 1));
    }

    //Don't hog all CPU time!
    System.Threading.Thread.Sleep(500);
}

, .NET . ( , ), ?

0

, . . , , , . , , . 1 .

try
{
    Process proc = Process.GetCurrentProcess();
    string strProcName = proc.ProcessName;
    Console.WriteLine("Process: " + strProcName);

    using (PerformanceCounter total_cpu = new PerformanceCounter("Processor", "% Processor Time", "_Total", true))
    {
        using (PerformanceCounter process_cpu = new PerformanceCounter("Process", "% Processor Time", strProcName, true))
        {
            for (; ; )
            {
                Console.CursorTop = 1;
                Console.CursorLeft = 0;

                float t = total_cpu.NextValue() ;
                float p = process_cpu.NextValue();
                Console.WriteLine(String.Format("Total CPU (%) = {0}\t\t\nApp CPU (%) = {1}\t\t\nApp RAM (KB) = {2}",
                    t, p, Process.GetCurrentProcess().WorkingSet64 / (1024)
                    ));

                System.Threading.Thread.Sleep(1000);
            }
        }
    }
}
catch(Exception ex)
{
    Console.WriteLine("Exception: " + ex);
}
0

All Articles