This is what im doing in form1:
void PopulateApplications()
{
DoubleBufferedd(dataGridView1, true);
int rcount = dataGridView1.Rows.Count;
int rcurIndex = 0;
foreach (Process p in Process.GetProcesses())
{
try
{
if (File.Exists(p.MainModule.FileName))
{
memoryUsage = Core.getallmemoryusage(p.ProcessName);
Core.getcpu(p.ProcessName);
cpuusage = Core.processes;
var icon = Icon.ExtractAssociatedIcon(p.MainModule.FileName);
Image ima = icon.ToBitmap();
ima = resizeImage(ima, new Size(25, 25));
ima = (Image)(new Bitmap(ima, new Size(25, 25)));
String status = p.Responding ? "Running" : "Not Responding";
if (rcurIndex < rcount - 1)
{
var currentRow = dataGridView1.Rows[rcurIndex];
currentRow.Cells[0].Value = ima;
currentRow.Cells[1].Value = p.ProcessName;
currentRow.Cells[2].Value = cpuusage;
currentRow.Cells[3].Value = memoryUsage;
currentRow.Cells[4].Value = status;
}
else
{
dataGridView1.Rows.Add(ima, p.ProcessName,cpuusage,memoryUsage, status);//false, ima, p.ProcessName, status);
}
rcurIndex++;
}
}
catch ( Exception e)
{
string t = "error";
}
}
if (rcurIndex < rcount - 1)
{
for (int i = rcurIndex; i < rcount - 1; i++)
{
dataGridView1.Rows.RemoveAt(rcurIndex);
}
}
}
Now the method in form1 PopulateApplications
, I call it from a timer tick event each 5 seconds.
Then I loop each time over the processes and get the memory usage and CPU usage.
This are the methods of memory and CPU in the class Core
.
With the memory method there is no problems. Working good and fast.
public static string getallmemoryusage(string processName)
{
var counter = new PerformanceCounter("Process", "Working Set - Private", processName);
privateMemeory = (counter.NextValue() / 1024 / 1024).ToString();
//string.Format("Private memory: {0}k", counter.NextValue() / 1024 / 1024);
return privateMemeory;
}
The problem is with the getcpu
method. I need to make it sleep every 1000ms few times to get the CPU usage. If I use a breakpoint on this method, I will get the value in the end. The problem is when I call the method in form1 each 5 seconds it's also calling and doing this getcpu
every 5 seconds and those threads sleep make it work very slow. If I will set the threads sleep to 10ms it will be faster but then I get on most processes 0% or 100% usage.
public static string getcpu(string name)
{
var cpuload = new PerformanceCounter("Processor", "% Processor Time", "_Total");
processes = Convert.ToInt32(cpuload.NextValue()) + "%";
System.Threading.Thread.Sleep(1000);
processes = cpuload.NextValue() + "%";
System.Threading.Thread.Sleep(1000);
processes = cpuload.NextValue() + "%";
System.Threading.Thread.Sleep(1000);
processes = cpuload.NextValue() + "%";
System.Threading.Thread.Sleep(1000);
processes = cpuload.NextValue() + "%";
System.Threading.Thread.Sleep(1000);
return processes;
}
When measuring % Processor Time
, the Thread.Sleep(1000)
is required since the .NextValue()
call determines the time, the processor was used since the last call to .NextValue()
. For further information on this calculation, check out http://blogs.msdn.com/b/bclteam/archive/2006/06/02/618156.aspx.
A couple of suggestions:
1) Since you are passing in the name of a process, I assume you want to measure the Processor Time of a single process. But as you are not using that parameter within your method, you are measuring the overall average system processor time instead.
So if you want to measure the performance for one single process, you could use something like:
public static double GetCpuUsage(Process process)
{
PerformanceCounter cpuCounter = new PerformanceCounter();
cpuCounter.CategoryName = "Process";
cpuCounter.InstanceName = process.ProcessName;
cpuCounter.CounterName = "% Processor Time";
// The first call will always return 0
cpuCounter.NextValue();
// That's why we need to sleep 1 second
Thread.Sleep(1000);
// The second call determines, the % of time that the monitored process uses on
// % User time for a single processor.
// So the limit is 100% * the number of processors you have.
double processorUsagePercent = cpuCounter.NextValue();
// Hence we need to divide by the number of processors to get the average CPU usage of one process during the time measured
return processorUsagePercent / Environment.ProcessorCount;
}
Please mind the difference between "Processor"
and "Process"
for the counter category.
2) Why are you calling .NextValue()
multiple times in a row and then return only the last value? That makes your method so slow. The two calculations shown in the example above are sufficient.
3) When you want to monitor multiple processes, you do not have to wait one second in between every call to .NextValue()
. You just have to make sure that at least one second has elapsed since the last time you called .NextValue()
on a specific counter. So for multiple processes you could have a method like that:
public static Dictionary<Process, double> GetCpuUsages(Process[] processes)
{
// One performance counter is required per process
PerformanceCounter[] counters = new PerformanceCounter[processes.Length];
// Instantiate a new counter per process
for(int i = 0; i < processes.Length; i++)
{
PerformanceCounter processorTimeCounter = new PerformanceCounter(
"Process",
"% Processor Time",
processes[i].ProcessName);
// Call NextValue once to have a reference value
processorTimeCounter.NextValue();
// Add it to the array
counters[i] = processorTimeCounter;
}
// Sleep one second to have accurate measurement
Thread.Sleep(1000);
// Here we store the processes along with their measurement in a dictionary
Dictionary<Process, double> cpuUsageDictionary = new Dictionary<Process, double>();
for (int i = 0; i < counters.Length; i++)
{
// Determine CPU usage and divide by the number of cores
double cpuUsage = counters[i].NextValue() / Environment.ProcessorCount;
// And now we add one key/value pair per process along with its cpu time measurement
cpuUsageDictionary.Add(processes[i], cpuUsage);
}
return cpuUsageDictionary;
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With