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.
Related
Looking to get the CPU/RAM %, I implemented the code below, however the counters always return CPU 100, RAM 0. I've tried 2sec invokes, same result. Googling this issue results in a thousand responses saying it's caused by no delay (which it usually is in the code samples seen), however given the invokes I've used, doesn't seem to be the cause here?
public class ScriptName : MonoBehaviour
{
PerformanceCounter cpuCounter;
PerformanceCounter ramCounter;
void Start()
{
cpuCounter = new PerformanceCounter("Processor", "% Processor Time", "_Total");
ramCounter = new PerformanceCounter("Memory", "Available MBytes");
cpuCounter.NextValue();
ramCounter.NextValue();
Invoke("UpdatePerformance", 1);
}
public void UpdatePerformance()
{
float cpu = cpuCounter.NextValue(); // Ouputs 100
float ram = ramCounter.NextValue(); // Outputs 0
Invoke("UpdatePerformance", 1); // 2 sec delay, same output
}
}
Thanks
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.
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
I have made a data logging application in C#. It connects to 4 USB sensors with the SerialPort class. I have the data received event threshold triggered on every byte. When data is received, the program checks to see if that byte is the end of the line. If it isn't, the input is added to a buffer. If it is a line end, the program adds a timestamp and writes the data and timestamp to a file (each input source gets a dedicated file).
Issues arise when using more than one COM port inputs. What I see in the output files is:
Any of the 4 Files:
...
timestamp1 value1
timestamp2 value2
timestamp3 value3
value4
value5
value6
timestamp7 value7
...
So, what it looks like is the computer isn't fast enough to get to all 4 interrupts before the next values arrive. I have good reason to believe that this is the culprit because sometimes I'll see output like this:
...
timestamp value
timestamp value
value
val
timestamp ue
timestamp value
...
It might be due to the fact that I changed the processor affinity to run only on Core 2. I did this because the timestamps I'm using are counted with processor cycles, so I can't have multiple time references depending on which core is running. I've put some of the code snippets below; any suggestions that might help with the dropped timestamps would be greatly appreciated!
public mainLoggerIO()
{
//bind to one cpu
Process proc = Process.GetCurrentProcess();
long AffinityMask = (long)proc.ProcessorAffinity;
AffinityMask &= 0x0002; //use only the 2nd processor
proc.ProcessorAffinity = (IntPtr)AffinityMask;
//prevent any other threads from using core 2
Process.GetCurrentProcess().PriorityClass = ProcessPriorityClass.High;
Thread.CurrentThread.Priority = ThreadPriority.Highest;
long frequency = Stopwatch.Frequency;
Console.WriteLine(" Timer frequency in ticks per second = {0}",
frequency);
long nanosecPerTick = (1000L * 1000L * 1000L) / frequency;
Console.WriteLine(" Timer is accurate within {0} nanoseconds",
nanosecPerTick);
if (Stopwatch.IsHighResolution)
MessageBox.Show("High Resolution Timer Available");
else
MessageBox.Show("No High Resolution Timer Available on this Machine");
InitializeComponent();
}
And so on. Each data return interrupt looks like this:
private void serialPort1_DataReceived(object sender, System.IO.Ports.SerialDataReceivedEventArgs e)
{
//serialPort1.DataReceived = serialPort1_DataReceived;
rawPort1Data = "";
rawPort1Data = serialPort1.ReadExisting();
this.Invoke((MethodInvoker)delegate { returnTextPort1(); });
}
The method returnTextPort#() is:
private void returnTextPort1()
{
if (string.Compare(saveFileName, "") == 0)//no savefile specified
return;
bufferedString += rawPort1Data;
if(bufferedString.Contains('\r')){
long timeStamp = DateTime.Now.Ticks;
textBox2.AppendText(nicknames[0] + " " + timeStamp / 10000 + ", " + rawPort1Data);
//write to file
using (System.IO.StreamWriter file = new System.IO.StreamWriter(#saveFileName, true))
{
file.WriteLine(nicknames[0] + " " + timeStamp / 10000 + ", " + rawPort1Data);//in Ms
}
bufferedString = "";
}
}
A cleaner approach would be to use a ConcurrentQueue<T> between the data received event handler and a separate Thread that will deal with the resulting data. That way the event handler can return immediately AND instead of modifying rawPort1 data in a totally non-thread-safe manner you could move to a thread-safe solution.
Create a Thread that reads from the concurrent queue, writes to the file and Invokes the UI changes. Note that writing to the file should NOT be on the UI thread.
Your ConcurrentQueue<T> can capture in the class T that you will implement: the port number, the data received and the timestamp at which it was received.
Note also that DateTime.Now is rarely ever the right answer, for most locations it jumps by an hour twice every year when daylight savings time starts or ends, instead of DateTime.UtcNow. Note however that neither has the accuracy you seem to be trying to obtain with your StopWatch code.
You should not need to manipulate processes or thread priorities to do this: the serial port has a buffer, you'll not miss data provided you handle it efficiently.
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?