C# Calculate CPU usage for one process with multiple instances - c#

I stuck with this problem:
I want to calculate what percentage of processor use a specific application , in this case that features 29 chrome instantiations . I am interested in how the processor consumes a total of 29 instantiations of chrome.The code I tried it:
private float GetCpuUsage(string ProcessName)
{
float cpuUsage = 0;
try
{
var ProcName = Process.GetProcessesByName(ProcessName);
var instances = new PerformanceCounter[ProcName.Length];
for (int i = 0; i < instances.Length; i++)
{
using (var TotalCpuUsage = new PerformanceCounter("Process", "% Processor Time", ProcName[i].ProcessName, true))
{
TotalCpuUsage.NextValue();
Thread.Sleep(1000); //for better aproximation cpu
double processNext = Math.Round((double)(TotalCpuUsage.NextValue() / Environment.ProcessorCount), 2);
Console.WriteLine("Processor Cpu:{0}, PidProcess:{1}", processNext, ProcName[i].Id);
cpuUsage += (float)processNext;
}
}
Console.WriteLine("Processor TotalCpu:{0}", cpuUsage);
return cpuUsage;
}
catch (Exception ex)
{
Message.Show(ex.Message + "\r\n" + ex.StackTrace);
return cpuUsage;
}
}
And I have these strange results:
Processor Cpu:6.51, PidProcess:18496
Processor Cpu:3.55, PidProcess:22056
Processor Cpu:20.54, PidProcess:16920
Processor Cpu:0, PidProcess:19420
Processor Cpu:0, PidProcess:7644
Processor Cpu:0, PidProcess:22500
Processor Cpu:14.07, PidProcess:19644
Processor Cpu:0, PidProcess:22004
Processor Cpu:3.55, PidProcess:23772
Processor Cpu:0, PidProcess:7948
Processor Cpu:6.91, PidProcess:22980
Processor Cpu:14.19, PidProcess:19464
Processor Cpu:0, PidProcess:18428
Processor Cpu:16, PidProcess:19408
Processor Cpu:0, PidProcess:20340
Processor Cpu:20.73, PidProcess:16660
Processor Cpu:9.37, PidProcess:7784
Processor Cpu:7.16, PidProcess:23984
Processor Cpu:0, PidProcess:8156
Processor Cpu:17.91, PidProcess:13272
Processor Cpu:10.1, PidProcess:20228
Processor Cpu:13.35, PidProcess:6568
Processor Cpu:3.55, PidProcess:6452
Processor Cpu:0, PidProcess:11668
Processor Cpu:0, PidProcess:16780
Processor Cpu:7.23, PidProcess:7036
Processor Cpu:0, PidProcess:19712
Processor Cpu:13.7, PidProcess:20316
Processor Cpu:3.45, PidProcess:20296
Processor TotalCpu:191.87
In what way I could tackle this problem ?? What to do to get some real results

I think the issue here may be that you are not taking into account that your system has multiple cores. You will need to divide the percentages by the number of cores available on the system. Take a look at the link below.
http://www.allenconway.net/2013/07/get-cpu-usage-across-all-cores-in-c.html

I know this is a slightly old question, but I'd just like to add that there's a fundamental flaw in this approach.
The CPU usage is calculated using a time slice. In the case of the code above, it's calculated over the period of a second (same as Task Manager uses for example, so nothing wrong there).
However, you're creating a PerformanceCounter instance per process and you're pretty much only using a single instance at a time.
In real terms what this means is... you query process (chrome) at 00:00 (mm:ss) and again at 00:01, then you query (chrome#1) at 00:01 and again at 00:02, (chrome#2) at 00:02 and again at 00:03 ... etc
So it is entirely possible that when you queried (chrome) it was using 100% CPU, but a second later when you query (chrome#1) the former is now using 0% CPU and the latter is now using 100%, so when you add them up you get 200% CPU usage.
You need to query all processes at the same time to get an accurate representation.

Related

Initialization of Performance Counters in .net are very slow

I am currently having two PerformanceCounters that are creating issues when my Windows Forms application is to be started.
The PerformanceCounters are created in the designer class of a UserControl that is initiated when the application starts. The counters, called performanceCounterMemory and performanceCounterProTime, are created to be able to give the user a real time feedback of the currently used RAM memory and process time (percentage). They are created with the following lines in the designer class
this.performanceCounterMemory = new System.Diagnostics.PerformanceCounter();
this.performanceCounterProTime = new System.Diagnostics.PerformanceCounter();
((System.ComponentModel.ISupportInitialize)(this.performanceCounterMemory)).BeginInit();
((System.ComponentModel.ISupportInitialize)(this.performanceCounterProTime)).BeginInit();
this.performanceCounterMemory.CategoryName = "Memory";
this.performanceCounterMemory.CounterName = "% used dedicated byte";
this.performanceCounterProTime.CategoryName = "Processor";
this.performanceCounterProTime.CounterName = "% Processor Time";
this.performanceCounterProTime.InstanceName = "_Total";
((System.ComponentModel.ISupportInitialize)(this.performanceCounterMemory)).EndInit();
((System.ComponentModel.ISupportInitialize)(this.performanceCounterProTime)).EndInit();
For reasons unknown the calls to the last two lines, the EndInit() calls, for both counters are really slow (10+ seconds) making the application very slow to start.
Why is this? What is the purpose of the EndInit calls and is it possible to make it faster?
To be able to use the counters the following two references are added by the lines
using System.Management.Instrumentation;
using System.Management;
The machine processor is: Intel(R) Core(TM) i7-3770 CPU # 3.40GHz
long memory = GC.GetTotalMemory(true);
You can use the following function (the true parameter tells GC to build first)
This is for RAM, I don't really understand, maybe it will help)

C# PerformanceMonitor only reports 0/100% with random, nonexistent spikes

I'm trying to make a sort of task manager -esque program using PerformanceMonitor and a chart. The CPU usage value is thrown onto a label and the chart, obviously, graphs it all out.
Problem is PerformanceMonitor only reports the CPU being at nothing or full, but the graph shows lots of little spikes in between, usually not matching the Windows Task Manager graph output.
I need to know how I can get PerformanceMonitor, or a similar C# product, to output viable, consistent, and accurate information into the graphing chart.
Code below. Timer interval is set to 25 for testing purposes currently.
public partial class formMain : Form
{
int usage;
int x = 1;
protected PerformanceCounter countCpu;
public formMain()
{
InitializeComponent();
myInit();
}
private void myInit()
{
countCpu = new PerformanceCounter("Processor", "% Processor Time", "_Total");
timerMain.Tick += new EventHandler(timerMain_Tick);
timerMain.Start();
}
private void timerMain_Tick(object sender, EventArgs e)
{
usage = Convert.ToInt32(countCpu.NextValue());
chartCpu.Series["CPU"].Points.AddXY(x, usage);
lblCpu.Text = Convert.ToString(usage.ToString()) + "%";
x++;
if(chartCpu.ChartAreas[0].AxisX.Maximum > chartCpu.ChartAreas[0].AxisX.ScaleView.Size)
{
chartCpu.ChartAreas[0].AxisX.ScaleView.Scroll(chartCpu.ChartAreas[0].AxisX.Maximum);
}
}
}
Here's a screenshot detailing what I mean.
Your spiky graph is a standard mishap when you use that PerformanceCounter. A processor only has two states, running full bore as fast as it can or turned off completely when no work needs to be done. The perf counter tells you how often it was running vs how often it was turned off since you last called the NextValue() method.
If you do that too fast then the resolution suffers, you get too many samples that are 0, 33, 50, 67 or 100. Make it really short and you'll only ever get 0 or 100. So the primary diagnostic here is that your Timer.Interval is too short. You probably left it at the default, 100 msec. You need to make it 1000 to emulate the behavior of Task Manager or Performance Monitor.
Furthermore, on modern version of Windows you need to use a different PerformanceCounter to emulate what you get from the Windows utilities. That counter lives in the "Processor Information" category, still called "% Processor Time". It is a tweaked counter that better represents the amount of work a modern processor really does. Which is convoluted, modern processors dynamically adjust their clock frequency based on the chip temperature, so the amount of work they do is affected by what they've done before. And they emulate an extra core with hyper-threading. That extra logical core however cannot do as much work as a real core. The tweaked counter tries to compensate for these effects.
It is because of your timer interval. Procesors don't have such a thing like CPU usage, they have CPU time (how much CPU spent time being active), so let's say your CPU time was 200 in now and will be 400 after a second, so (400 - 200) ms / 1000 ms * 100% equals 20 % CPU usage. Now lets say you need to calculate your CPU usage each 1 ms. Because CPU time is only integer, after that 1 ms you are trying to calculate, your CPU time will likely increase in 1 or even not increase at all. So (201 - 200) ms / 1 ms * 100% equals 100 %. The higher your interval is, the more accuracy you'll get in CPU usage calculation.
Managed to accidentally fix this by removing the myInit method and adjusting the code.
Final code:
public partial class formMain : Form
{
int usage;
int x = 1;
protected PerformanceCounter countCpu = new PerformanceCounter("Processor", "% Processor Time", "_Total");
public formMain()
{
InitializeComponent();
timerMain.Tick += new EventHandler(timerMain_Tick);
timerMain.Start();
}
private void timerMain_Tick(object sender, EventArgs e)
{
usage = Convert.ToInt32(countCpu.NextValue());
chartCpu.Series["CPU"].Points.AddXY(x, usage);
lblCpu.Text = Convert.ToString(usage.ToString()) + "%";
x++;
if(chartCpu.ChartAreas[0].AxisX.Maximum > chartCpu.ChartAreas[0].AxisX.ScaleView.Size)
{
chartCpu.ChartAreas[0].AxisX.ScaleView.Scroll(chartCpu.ChartAreas[0].AxisX.Maximum);
}
}
}

Why i'm not getting the overall cpu usage results like in the windows task manager? [duplicate]

I'm currently doing this:
PerformanceCounter cpuUsage = new PerformanceCounter("Processor", "% Processor Time", "_Total");
cpuUsage.NextValue();
System.Threading.Thread.Sleep(1000);
RV = cpuUsage.NextValue();
I call the function periodically to get CPU usage. When I monitor the system in TaskManager, the CPU usage reported by PerformanceCounter is consistently 15-20% higher than what TaskManager reports (30% in TaskManager = 50% from PerformanceCounter).
Maybe there's documentation that I overlooked, but does anyone have an explanation? Maybe the CPU usage at the instant it checks is higher and task manager reports an average?
new PerformanceCounter("Processor", ...);
You are using the wrong counter if you insist on seeing an exact match with Task Manager or Perfmon. Use "Processor Information" instead of "Processor". The reason these counters show different values is addressed pretty well in this blog post. Which counter is "right" is a question I wouldn't want to touch with a ten-foot pole :)
Did not have luck with accepted answer, so adding my comment as an answer to hopefully help people find this through online search a little better.
var counter = new PerformanceCounter("Processor Information", "% Processor Utility", "_Total");

about using cpucounter and ramcounter

how to detect cpuusage and ram usage of a remote host using c#??
You could use the C# PerformanceCounter class to get this done. It's relatively simple to create a read-only counter:
PerformanceCounter cpuCounter = new PerformanceCounter(category, counter, instance, machine)
The documentation is available here: http://msdn.microsoft.com/en-us/library/9ffskxdc(v=VS.90).aspx
I'm not 100% sure that these are the exact values you want, but these may work:
CPU:
category = Processor
counter = % Processor Time
instance = _Total
RAM:
category = Memory
counter = Available MBytes
instance = (use String.Empty)
Performance Counters can be very tricky if you want your app to work on all modern MS OSs. Things get even more complicated if you want your app to run as regular (non-admin) user.
But that should get you started.
-- Dan

What is the correct Performance Counter to get CPU and Memory Usage of a Process?

How can I get the CPU and Memory usage of a particular process using the .NET PerformanceCounter class? And also what is the difference between
Processor\% Processor Time and Process\% Processor Time?
I am a bit confused between these two.
From this post:
To get the entire PC CPU and Memory usage:
using System.Diagnostics;
Then declare globally:
private PerformanceCounter theCPUCounter =
new PerformanceCounter("Processor", "% Processor Time", "_Total");
Then to get the CPU time, simply call the NextValue() method:
this.theCPUCounter.NextValue();
This will get you the CPU usage
As for memory usage, same thing applies I believe:
private PerformanceCounter theMemCounter =
new PerformanceCounter("Memory", "Available MBytes");
Then to get the memory usage, simply call the NextValue() method:
this.theMemCounter.NextValue();
For a specific process CPU and Memory usage:
private PerformanceCounter theCPUCounter =
new PerformanceCounter("Process", "% Processor Time",
Process.GetCurrentProcess().ProcessName);
where Process.GetCurrentProcess().ProcessName is the process name you wish to get the information about.
private PerformanceCounter theMemCounter =
new PerformanceCounter("Process", "Working Set",
Process.GetCurrentProcess().ProcessName);
where Process.GetCurrentProcess().ProcessName is the process name you wish to get the information about.
Note that Working Set may not be sufficient in its own right to determine the process' memory footprint -- see What is private bytes, virtual bytes, working set?
To retrieve all Categories, see Walkthrough: Retrieving Categories and Counters
The difference between Processor\% Processor Time and Process\% Processor Time is Processor is from the PC itself and Process is per individual process. So the processor time of the processor would be usage on the PC. Processor time of a process would be the specified processes usage. For full description of category names: Performance Monitor Counters
An alternative to using the Performance Counter
Use System.Diagnostics.Process.TotalProcessorTime and System.Diagnostics.ProcessThread.TotalProcessorTime properties to calculate your processor usage as this article describes.
Pelo Hyper-V:
private PerformanceCounter theMemCounter = new PerformanceCounter(
"Hyper-v Dynamic Memory VM",
"Physical Memory",
Process.GetCurrentProcess().ProcessName);
To get the value similar to that displayed in task manager
PerformanceCounter total_cpu = new PerformanceCounter("Process", "% Processor Time", "_Total");
PerformanceCounter process_cpu = new PerformanceCounter("Process", "% Processor Time", Process.GetCurrentProcess().ProcessName);
Console.writeln (((process_cpu.NextValue()/( (Environment.ProcessorCount)* total_cpu.NextValue()))*100) )

Categories