Tricky one for you all. WMI and CPU Utilisation.

Hey all,
I have created the following class to get CPU Utilisation data using WMI as follows;




Imports System.Management

Public 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 Exception

Carthew.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 Then

mFirstRun = False

mResult = 0

End If

Return mResult

Catch ex As Exception

Carthew.Gizmo.SaveErrorLog(ex, True)

End Try

End Function

#End Region

End 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



Answer this question

Tricky one for you all. WMI and CPU Utilisation.

  • SteveMargolis

    Hi Grant,

    I tried your code on my computer, and it worked just fine Tongue Tied

    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

    Hi Grant,

    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

    For some reason the code does not format correctly when I post Tongue Tied

  • PMace

    Thanks Dustin.
    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

    Thanks DMan,

    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

    Ok, that's great Dustin...

    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.




  • Tricky one for you all. WMI and CPU Utilisation.