C# - Performance Counter lower than Taskmanager % [duplicate] - c#

This question already has answers here:
PerformanceCounter reporting higher CPU usage than what's observed
(2 answers)
Closed 2 years ago.
I try to make a class which will fetch different usages from the pc, the problem that I have atm is that the CPU usage is under what Task Manager displays (with about 10%).
Can you please have a look and point me in the right direction ? Please no answers without explanation, I want to learn !
Here is what I have atm :
using System.Diagnostics;
using System.Net.NetworkInformation;
namespace ConsoleApplication2
{
class UsageFetcher
{
ulong totalRAM;
PerformanceCounter cpuUsage;
PerformanceCounter ramUsage;
PerformanceCounter diskUsage;
NetworkInterface[] networkUsage;
public UsageFetcher()
{
// Fetching total amount of RAM to be able to determine used persantage
//totalRAM = new Microsoft.VisualBasic.Devices.ComputerInfo().TotalPhysicalMemory;
totalRAM = this.getTotalRam();
// Creating a new Perfromance Counter who will be used to get the CPU Usage
cpuUsage = new PerformanceCounter();
// Setting it up to fetch CPU Usage
cpuUsage.CategoryName = "Processor";
cpuUsage.CounterName = "% Processor Time";
cpuUsage.InstanceName = "_Total";
/*
* Fetching the first two reads
* First read is always 0 so we must elimiate it
*/
cpuUsage.NextValue();
cpuUsage.NextValue();
// Creating a new Performance Counter who will be used to get the Memory Usage
ramUsage = new PerformanceCounter();
// Setting it up to fetch Memory Usage
ramUsage.CategoryName = "Memory";
ramUsage.CounterName = "Available Bytes";
// Fetching the first two reads !! Same reason as above !!
ramUsage.NextValue();
ramUsage.NextValue();
}
public string getCPUUsage()
{
/*
* Requesting the usage of the CPU
* It is returned as a float thus I need to call ToString()
*/
return cpuUsage.NextValue().ToString();
}
public string getMemUsage()
{
// Requesting memory usage and calculate how much is free
return (100 -ramUsage.NextValue() / totalRAM * 100).ToString();
}
public ulong getTotalRam()
{
return new Microsoft.VisualBasic.Devices.ComputerInfo().TotalPhysicalMemory ;
}
}
}

According to this SO post here: Why the cpu performance counter kept reporting 0% cpu usage?
You need to sleep for at least a second for the NextValue() method to return a decent result.
Try adding a call to Sleep between your calls to NextValue and see what you get.

Related

c# CPU and Memory Monitor Console app keeps warning me that mu CPU load is at 100%

I'm assuming I have found myself some sort of a nasty bug.
I have recently tried to create a console application in c# that prints the CPU Load & available memory every second. Whilst this goes on I have made sure that the application only warns about the CPU usage when the CPU Load goes over 80 percent. With a much more serious warning at 100% as you will see.
However, when i run the application it continually warns me that the CPU is at 100%, even though I know it shouldn't be running anywhere near that. I downloaded CPU Burn In to test the app and push the CPU to 100%, However I am 100 percent sure that it has been disabled the whole time.
I will post my code below.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Diagnostics;
using System.Threading;
using System.Speech.Synthesis;
namespace CpuandMemoryMonitor
{
class Program
{
/// <summary>
/// Entry Point into the Program | Program: CPU & Memory Monitor |By:
Andrew.
/// </summary>
///
static void Main(string[] args)
{
#region My performance Counters
// This will greet the user in the default voice
SpeechSynthesizer synth = new SpeechSynthesizer();
synth.Speak("Welcome to the CPU and Memory Monitor");
// This will pull the current CPU load in percentage.
PerformanceCounter perfCpuCount = new PerformanceCounter("Processor Information", "% Processor Time", "_Total");
// This will pull the current available Memory in Megabytes
PerformanceCounter perfMemCount = new PerformanceCounter("Memory", "Available MBytes");
// This will give us system uptime (in Seconds)
PerformanceCounter perfUptimecount = new PerformanceCounter("System", "System Up Time");
#endregion
#region Perfromance Counters Program Loop
//Infinite While Loop.
while (true)
{
// Get the current perforance counter values
int currentcpupercentage = (int)perfCpuCount.NextValue();
int currentavailablememory = (int)perfMemCount.NextValue();
//Print the performance counter values to the console screen
Console.WriteLine("CPU Load: {0}%", currentcpupercentage);
Console.WriteLine("Available Memory: {0}MB", currentavailablememory);
// Speech synthasiser warns user when CPU Load is above 80 percent
if (currentcpupercentage > 80)
{
///If CPU Load is at 100 % Warn the user in a a female voice!
if (currentcpupercentage == 100)
{
synth.SelectVoiceByHints(VoiceGender.Female);
string cpuLoadVocalMessage = String.Format("Oh dear! You're CPU is about to catch on Fire!");
synth.Speak(cpuLoadVocalMessage);
}
else
//If CPU Load is at 80 % Warn the user in a a male voice!
{
synth.SelectVoiceByHints(VoiceGender.Male);
string cpuLoadVocalMessage = String.Format("The Current Cpu Load is {0}", currentcpupercentage);
synth.Speak(cpuLoadVocalMessage);
}
// Speech synthasiser warns user when memory is less then 1 gigabyte
if (currentavailablememory < 1024)
{
// If CPU Load is at 100 % Warn the user ina a female voice!
string memavailableVocalMessage = string.Format("You currently have {0} gigabytes of memory available", currentavailablememory / 1024);
synth.Speak(memavailableVocalMessage);
}
//Sleep for 1 second
Thread.Sleep(1000);
}
#endregion
}
}
}
}
You have an infinite loop, if you have an infinite loop the computer will run the code continuously. As others have pointed out in the comments, you should use some form of timer in order to only poll at specific intervals. Even better you can use a WMI Event watcher to get called only when the alarm is hit.
Google WMI Events or read things like;
https://msdn.microsoft.com/en-us/library/aa393013(v=vs.85).aspx

get current cpu usage using c# in asp.net framework

I would like to find out the current CPU usage using the codes below(c# in asp.net framework). However it gives me "0% of CPU usage" when I try to run the program. When I check my task manager, I found out that the actual total CPU usage is more than 5%. Does anyone know what is wrong with the code below?
public partial class cpuUsage : System.Web.UI.Page
{
PerformanceCounter cpu;
protected void Page_Load(object sender, EventArgs e)
{
cpu = new PerformanceCounter();
cpu.CategoryName = "Processor";
cpu.CounterName = "% Processor Time";
cpu.InstanceName = "_Total";
lblCPUUsage.Text = getCurrentCpuUsage();
}
public string getCurrentCpuUsage()
{
return cpu.NextValue() + "%";
}
}
The first value returned by a PerformanceCounter will always be 0. You'll need a Timer or Thread that keeps monitoring the value in the background. This code for example will output the correct value every second (don't use this actual code, it's quick and dirty):
new Thread(() =>
{
var cpu = new PerformanceCounter
{
CategoryName = "Processor",
CounterName = "% Processor Time",
InstanceName = "_Total"
}
while (true)
{
Debug.WriteLine("{0:0.0}%", cpu.NextValue());
Thread.Sleep(1000);
}
}).Start();
Make sure to read the remarks of the PerformanceCounter.NextValue method:
If the calculated value of a counter depends on two counter reads, the first read operation returns 0.0. Resetting the performance counter properties to specify a different counter is equivalent to creating a new performance counter, and the first read operation using the new properties returns 0.0. The recommended delay time between calls to the NextValue method is one second, to allow the counter to perform the next incremental read.

How to get performance data?

I want to get the performance data like in the performance tab in the task manager window.
I got this code:
using (PerformanceCounter pCounter = new PerformanceCounter())
{
pCounter.CategoryName = "Processor"; //this get me the cpu usage
pCounter.CounterName = "% Processor Time";
pCounter.InstanceName = "_Total";
// will always start at 0
pCounter.NextValue();
System.Threading.Thread.Sleep(1000);
//now matches task manager reading
float cpuUsage = pCounter.NextValue();
pCounter.CategoryName = "Memory";
pCounter.CounterName = "Available MBytes"; //this gets me the available memory
pCounter.InstanceName = string.Empty;
}
I also need:
The up time (time the server is active HH:mm:ss)
Number of processes
Number of threads
Ethernet usage
I have no idea how to get this data...
The .net framework provides the System.Diagnostics class with a plethora of methods to access system info including performance data.
https://msdn.microsoft.com/en-us/library/vstudio/System.Diagnostics%28v=vs.90%29.aspx

How to run CPU at a given load (% CPU utilization)?

Is it possible to freeze CPU usage that is shown in in Windows Task Manager? I wish to freeze the load as specific values like 20%, 50%, 70% etc. from my program.
(This is to analyse how much power the PC is consuming with regard to CPU usage.)
Is this possible?
My first naive attempt would be to spawn 2x threads as cores -- each thread in the highest priority and then, within each thread, run a busy-loop and do some work. (More threads than cores is to "steal" all the time I can get from other threads in windows :-)
Using some kind of API to read the CPU load (perhaps WMI or performance counters?) and I would then make each thread 'yield' from the busy loop (sleep for a certain amount of time each loop) until I get the approximate load in the feedback cycle.
This cycle would be self-adjusting: too high load, sleep more. Too low load, sleep less. It's not an exact science, but I think that with some tweaking a stable load can be obtained.
But, I have no idea, really :-)
Happy coding.
Also, consider power management -- sometimes it can lock a CPU at a "max %". Then fully load the CPU and it will max out at that limit. (Windows 7, at least, has a built-in feature to do this, depending upon CPU and chip-set -- there are likely many 3rd party tools.)
The situation becomes rather confusing with newer CPUs that dynamically clocked based on load and temperature, etc.
Here is my attempt at the "naive" approach for .NET 3.5. Make sure to include the System.Management reference.
The CPU utilization as reported by the Task Manager hovers within a few percent of the target -- average seems pretty darn close -- on my system. YMMV, but there is some flexibility for adjustment.
Happy coding (again).
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Management;
using System.Threading;
using System.Diagnostics;
namespace CPULoad
{
class Program
{
// What to try to get :-)
static int TargetCpuUtilization = 50;
// An average window too large results in bad harmonics -- keep it small.
static int AverageWindow = 5;
// A somewhat large number gets better results here.
static int ThreadsPerCore = 8;
// WMI is *very slow* compared to a PerformanceCounter.
// It still works, but each cycle is *much* longer and it doesn't
// exhibit as good of characteristics in maintaining a stable load.
// (It also seems to run a few % higher).
static bool UseWMI = false;
// Not sure if this helps -- but just play about :-)
static bool UseQuestionableAverage = true;
static int CoreCount () {
var sys = new ManagementObject("Win32_ComputerSystem.Name=\"" + Environment.MachineName + "\"");
return int.Parse("" + sys["NumberOfLogicalProcessors"]);
}
static Func<int> GetWmiSampler () {
var searcher = new ManagementObjectSearcher(
#"root\CIMV2",
"SELECT PercentProcessorTime FROM Win32_PerfFormattedData_PerfOS_Processor");
return () => {
var allCores = searcher.Get().OfType<ManagementObject>().First();
return int.Parse("" + allCores["PercentProcessorTime"]);
};
}
static Func<int> GetCounterSampler () {
var cpuCounter = new PerformanceCounter {
CategoryName = "Processor",
CounterName = "% Processor Time",
InstanceName = "_Total",
};
return () => {
return (int)cpuCounter.NextValue();
};
}
static Func<LinkedList<int>, int> StandardAverage () {
return (samples) => {
return (int)samples.Average();
};
}
// Bias towards newest samples
static Func<LinkedList<int>, int> QuestionableAverage () {
return (samples) => {
var weight = 4.0;
var sum = 0.0;
var max = 0.0;
foreach (var sample in samples) {
sum += sample * weight;
max += weight;
weight = Math.Min(4, Math.Max(1, weight * 0.8));
}
return (int)(sum / max);
};
}
static void Main (string[] args) {
var threadCount = CoreCount() * ThreadsPerCore;
var threads = new List<Thread>();
for (var i = 0; i < threadCount; i++) {
Console.WriteLine("Starting thread #" + i);
var thread = new Thread(() => {
Loader(
UseWMI ? GetWmiSampler() : GetCounterSampler(),
UseQuestionableAverage ? QuestionableAverage() : StandardAverage());
});
thread.IsBackground = true;
thread.Priority = ThreadPriority.Highest;
thread.Start();
threads.Add(thread);
}
Console.ReadKey();
Console.WriteLine("Fin!");
}
static void Loader (Func<int> nextSample, Func<LinkedList<int>, int> average) {
Random r = new Random();
long cycleCount = 0;
int cycleLength = 10;
int sleepDuration = 15;
int temp = 0;
var samples = new LinkedList<int>(new[] { 50 });
long totalSample = 0;
while (true) {
cycleCount++;
var busyLoops = cycleLength * 1000;
for (int i = 0; i < busyLoops; i++) {
// Do some work
temp = (int)(temp * Math.PI);
}
// Take a break
Thread.Sleep(sleepDuration);
{
// Add new sample
// This seems to work best when *after* the sleep/yield
var sample = nextSample();
if (samples.Count >= AverageWindow) {
samples.RemoveLast();
}
samples.AddFirst(sample);
totalSample += sample;
}
var avg = average(samples);
// should converge to 0
var conv = Math.Abs(TargetCpuUtilization - (int)(totalSample / cycleCount));
Console.WriteLine(string.Format("avg:{0:d2} conv:{1:d2} sleep:{2:d2} cycle-length:{3}",
avg, conv, sleepDuration, cycleLength));
// Manipulating both the sleep duration and work duration seems
// to have the best effect. We don't change both at the same
// time as that skews one with the other.
// Favor the cycle-length adjustment.
if (r.NextDouble() < 0.05) {
sleepDuration += (avg < TargetCpuUtilization) ? -1 : 1;
// Don't let sleep duration get unbounded upwards or it
// can cause badly-oscillating behavior.
sleepDuration = (int)Math.Min(24, Math.Max(0, sleepDuration));
} else {
cycleLength += (avg < TargetCpuUtilization) ? 1 : -1;
cycleLength = (int)Math.Max(5, cycleLength);
}
}
}
}
}
While Windows is a preemptive operating system, code which runs in Kernel Mode -- such as drivers -- is preempted by far less. While not doable in C# AFAIK, this should yield a method of stricter load control than the above, but also has a good bit more complexity (and the ability to crash the entire system :-)
There is Process.PriorityClass, but setting this to anything but normal yielded lest consistent behavior for me.
I don't know if you can do that, but you can change the thread priority of the executing thread via the Priority property. You would set that by:
Thread.CurrentThread.Priority = ThreadPriority.Lowest;
Also, I don't think you really want to cap it. If the machine is otherwise idle, you'd like it to get busy on with the task, right? ThreadPriority helps communicate this to the scheduler.
Reference : How to restrict the CPU usage a C# program takes?

C#: how to obtain the current clock speed of an Intel i-series CPU when TurboBoost is activated

I know that it's possible to get this information - Intel's own TurboBoost sidebar gadget appears to use an ActiveX control to determine the current clock speed of an i3/i5/i7 CPU when TurboBoost is active. However, I'm wanting to do this programmatically in C# - obtaining the CurrentClockSpeed value from WMI tops out at the set maximum clock speed of the CPU, so in TurboBoost mode, it doesn't report the current actual clock speed.
If you want to get the turbo speed, you can make use of the "% Processor Performance" performance counter and multiply it with the WMI "MaxClockSpeed" as follows:
private string GetCPUInfo()
{
PerformanceCounter cpuCounter = new PerformanceCounter("Processor Information", "% Processor Performance", "_Total");
double cpuValue = cpuCounter.NextValue();
Thread loop = new Thread(() => InfiniteLoop());
loop.Start();
Thread.Sleep(1000);
cpuValue = cpuCounter.NextValue();
loop.Abort();
foreach (ManagementObject obj in new ManagementObjectSearcher("SELECT *, Name FROM Win32_Processor").Get())
{
double maxSpeed = Convert.ToDouble(obj["MaxClockSpeed"]) / 1000;
double turboSpeed = maxSpeed * cpuValue / 100;
return string.Format("{0} Running at {1:0.00}Ghz, Turbo Speed: {2:0.00}Ghz", obj["Name"], maxSpeed, turboSpeed);
}
return string.Empty;
}
The InfiniteLoop method is simply an integer that gets 1 added and subtracted:
private void InfiniteLoop()
{
int i = 0;
while (true)
i = i + 1 - 1;
}
The InfiniteLoop method is just added to give the CPU something to do and turbo in the process. The loop is allowed to run for a second before the next value is taken and the loop aborted.
I also posted this answer on this question.
I do not believe it's possible to obtain this information with only safe/managed C# code, since WMI does not seem to supply this information. So i think you will need to use the CPUID instruction to get detailed information from the CPU that executes the instruction.
This documentation from Intel might help get you started:
http://www.intel.com/assets/pdf/appnote/241618.pdf
And here's some unsafe code to use with C#:
An attempt to bring CPUID to C#
Also see page 7 of:
Intel® Turbo Boost Technology in Intel® Core™ Microarchitecture (Nehalem) Based Processors

Categories