I have created the following class to get CPU Utilisation data using WMI as follows;
Imports System.ManagementPublic Class WMIProcessing# Region " Definitions " 'WMI Objects... Private mManagementScope As New System.Management.ManagementScope Private mObjectSearcher As System.Management.ManagementObjectSearcher Private mCollection As System.Management.ManagementObjectCollection Private mObject As System.Management.ManagementObject 'Data Storage... Private mOldData As RawData Private mNowData As RawData Private mResult As Double 'Flag to indicate first run... Private mFirstRun As Boolean = True 'Data Storage Structure... Private Structure RawData Public RAWPercentProcessorTime As ULong Public TimeStamp As ULong End Structure# End Region# Region " Constructor " Public Sub New() Try 'Connect to WMI namespace...mManagementScope.Connect() If mManagementScope.IsConnected = False Then Throw New Exception("Could not connect to WMI namespace") End If 'Build query...mObjectSearcher = New System.Management.ManagementObjectSearcher("Select * From Win32_PerfRawData_PerfOS_Processor where Name = '_Total'") 'Initialize mOldData...mOldData.RAWPercentProcessorTime = 0 mOldData.TimeStamp = 0 Catch ex As ExceptionCarthew.Gizmo.SaveErrorLog(ex, True) End Try End Sub# End Region# Region " Get Data Functions " Friend Function GetProcessorUtilisation() As Double Try 'Run the WMI Query to get the current Win32_PerfRawData_PerfOS_Processor data...mCollection = mObjectSearcher.Get() 'Store the data... For Each mObject In mCollection 'Get current data...mNowData.RAWPercentProcessorTime = CULng(mObject.GetPropertyValue("PercentProcessorTime"))mNowData.TimeStamp = CULng(mObject.GetPropertyValue("Timestamp_Sys100NS")) Next 'Calculate CPU % Utilisation...mResult = (1 - ((mNowData.RAWPercentProcessorTime - mOldData.RAWPercentProcessorTime) / (mNowData.TimeStamp - mOldData.TimeStamp))) * 100 'Store data for next refresh...mOldData = mNowData 'Check for the first run through... If mFirstRun = True ThenmFirstRun = FalsemResult = 0 End If Return mResult Catch ex As ExceptionCarthew.Gizmo.SaveErrorLog(ex, True) End Try End Function# End RegionEnd Class |
I call the GetProcessorUtilisation function every second.
The strange thing is, if the CPU is not busy, it returns -0.03%. I don't quite understand why, seeing as the variables used are Unsigned Integers
Anyone got any ideas as to why this would be
Note:
http://msdn.microsoft.com/library/default.asp url=/library/en-us/wmisdk/wmi/example__obtaining_raw_performance_data.asp

Tricky one for you all. WMI and CPU Utilisation.
SteveMargolis
I tried your code on my computer, and it worked just fine
P.S. The formatting issue seems to be with Internet Explorer. I have to use FireFox when using these forums, as the code will copy/paste just fine in FireFox.
Dustin.
craig kelly-soens xpectworld.com
I tried it for about 4-5 minutes.
I made a form, with a timer, and called the getcputime() every 50ms.
The output was correct. I tried it while running a game i'm making that uses cpu time pretty good, and it read out fine.
At idle, it displayed almost always 0%. I never saw it go past 80, but i don't think i used that much cpu time.
It did jump around alot though, maybe because i can't see it as a graph, but i'm sure it was ok.
I ran another test, and outputed values to a textbox. Here's the return i got.
0 0 0 0 0 0
57.14 70.59 100 33.33 28.57 14.29
14.29 42.86 57.14 14.29 42.86 57.14
14.29 14.29 42.86 42.86 42.86 42.86
28.57 28.57 42.86 14.29 25 33.33
14.29 28.57 92.86 100 33.33 14.29
75 100 100 100 100 100
100 100 100 100 33.33 42.86
14.29 28.57 55.56 80 42.86 14.29
28.57 71.43 66.67 33.33 16.67 57.14
42.86 42.86 87.5 50 28.57 14.29
14.29 14.29 57.14 57.14 28.57 87.5
100 71.43 28.57 28.57 14.29 12.5
14.29 14.29 14.29 14.29 28.57 28.57
42.86 14.29 28.57 14.29 42.86 42.86
28.57 42.86 14.29 14.29 14.29 28.57
42.86 14.29 14.29 14.29 28.57 28.57
28.57 14.29 14.29 14.29 28.57 14.29
28.57 28.57 14.29 14.29 14.29 14.29
28.57 71.43 42.86 14.29 14.29 14.29
14.29 14.29 28.57 28.57 42.86 14.29
14.29 14.29 42.86 85.71 75 83.33
100 66.67 57.14 100 100 100
100 100 100 100 100 85.71
14.29 28.57 14.29 28.57 14.29 28.57
42.86 28.57 14.29 28.57 28.57 14.29
14.29 14.29 28.57 28.57 28.57 28.57
14.29 14.29 28.57 14.29 28.57 14.29
14.29 14.29 14.29 28.57 28.57 28.57
28.57 42.86 14.29 28.57 42.86 28.57
28.57 14.29 28.57 42.86 14.29 14.29
28.57 28.57 14.29 28.57 28.57 14.29
14.29 28.57 28.57
Dustin.
Anthony Chennai
PMace
Just confirming, was your cpu idle at the time, ie. returning as little utilisation as possible
Did you monitor it for long
Grant.
DevMate
<quote>
mResult = (1 - ((mNowData.RAWPercentProcessorTime - mOldData.RAWPercentProcessorTime) / (mNowData.TimeStamp - mOldData.TimeStamp))) * 100
</quote>
mresult is declared as a double which is signed! Logically inorder to get a negitive number mNowData.RAWPercentProcessorTime < mOldData.RAWPercentProcessorTime
Talwalkar
That explains the unsigned number (obvious as it is), but the consuming object requires Double, so I will stick with it.
It doe's not explain why the number is calculating as negative though. The data coming back from the WMI Namespace seems to be calculating as negative, even though I have followed the MSDN example.
As it is, I have put a simple "if" statement in to remove negative numbers. I need to understand the RAW data that is returned by the WMI Object to understand why it is calculating as negative.
I will see if I can find some more information on it.
brentserbus
I don't know where the negative number is coming from then.
It is not a major issue, so I think I will ignore it. The CPU Usage data from the class is actually more accurate than the data you get from PerfMon and the Performance Objects in .NET.
When I first started working at getting the CPU Utilisation data I started using the performance monitor objects from the framework and found that Task Manager had more acurate data in it. That is why I moved to getting the data using WMI.
Thanks for you help.
Regards,
Grant.